Go: // Warshall–Floyd Algorithm

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

func main() {
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		n, _ := strconv.Atoi(buf[0])
		m, _ := strconv.Atoi(buf[1])
		if n == 0 && m == 0 {
			break
		}
		c_matrix := make([][]int, m)
		for i := range c_matrix {
			c_matrix[i] = make([]int, m)
		}
		t_matrix := make([][]int, m)
		for i := range t_matrix {
			t_matrix[i] = make([]int, m)
		}
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			a, _ := strconv.Atoi(buf_[0])
			b, _ := strconv.Atoi(buf_[1])
			c, _ := strconv.Atoi(buf_[2])
			t, _ := strconv.Atoi(buf_[3])
			c_matrix[a-1][b-1] = c
			t_matrix[a-1][b-1] = t
		}
		c_dist := make([][]int, m)
		c_prev := make([][]int, m)
		t_dist := make([][]int, m)
		t_prev := make([][]int, m)
		for i := 0; i < m; i++ {
			c_dist[i] = make([]int, m)
			c_prev[i] = make([]int, m)
			t_dist[i] = make([]int, m)
			t_prev[i] = make([]int, m)
		}
		for i := 0; i < m; i++ {
			for j := 0; j < m; j++ {
				if c_matrix[i][j] == 0 {
					c_dist[i][j] = INF
					c_prev[i][j] = -1
				} else {
					c_dist[i][j] = c_matrix[i][j]
					c_prev[i][j] = i
				}
				if t_matrix[i][j] == 0 {
					t_dist[i][j] = INF
					t_prev[i][j] = -1
				} else {
					t_dist[i][j] = t_matrix[i][j]
					t_prev[i][j] = i
				}
			}
			c_dist[i][i] = 0
			t_dist[i][i] = 0
		}
		for k := 0; k < m; k++ {
			for i := 0; i < m; i++ {
				for j := 0; j < m; j++ {
					c_newlen := c_dist[i][k] + c_dist[k][j]
					if c_newlen < c_dist[i][j] {
						c_dist[i][j] = c_newlen
						c_prev[i][j] = c_prev[k][j]
					}
				}
			}
		}
		for k := 0; k < m; k++ {
			for i := 0; i < m; i++ {
				for j := 0; j < m; j++ {
					t_newlen := t_dist[i][k] + t_dist[k][j]
					if t_newlen < t_dist[i][j] {
						t_dist[i][j] = t_newlen
						t_prev[i][j] = t_prev[k][j]
					}

				}
			}
		}
		scanner.Scan()
		k, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < k; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			p, _ := strconv.Atoi(buf_[0])
			q, _ := strconv.Atoi(buf_[1])
			r, _ := strconv.Atoi(buf_[2])
			switch r {
			case 0:
				fmt.Println(c_dist[p-1][q-1])
			case 1:
				fmt.Println(t_dist[p-1][q-1])
			}
		}
	}
}

Python: import sys
import heapq as h

inf = sys.maxsize

# おまじない
class heapq:
    def __init__(self):
        self.q = []

    def push(self,v):
        h.heappush(self.q, v)
    
    def pop(self):
        return h.heappop(self.q)

    def is_empty(self):
        return len(self.q) == 0

# 入力:graphと始点s
# 出力:始点sから各頂点tへの距離dist
def shortestPath0(graph, s):
    n = len(graph)

    dist    = [inf for _ in range(n)]
    visited = [False for _ in range(n)]
    dist[s] = 0

    while True:
        idx, u  = -1, inf
        for i in range(n):
            if not visited[i] and dist[i] < u:
                idx = i
                u = dist[i]
        
        if u == inf: break
        
        visited[idx] = True

        for (next, w) in graph[idx]:
            newdist = w + dist[idx]
            if newdist < dist[next]:
                dist[next] = newdist
    return dist

def shortestPath1(graph, s):
    n = len(graph)

    dist    = [inf for _ in range(n)]
    visited = [False for _ in range(n)]
    
    q = heapq()
    q.push((0, s))

    while not q.is_empty():
        (cur_dist, v) = q.pop()

        if visited[v] or dist[v] <= cur_dist:
            continue

        dist[v] = cur_dist
        visited[v] = True

        for next, w in graph[v]:
            if not visited[next] and dist[v] + w < dist[next]:
                q.push((dist[v] + w, next))

    return dist

def main():
    while True:
        n, m = map(int, input().split())
        if n == 0 and m == 0:
            break
        # 隣接リスト
        tgraph = [[] for _ in range(m)]
        cgraph = [[] for _ in range(m)]
        
        for i in range(n):
            a, b, cost, time = map(int, input().split())
            a -= 1
            b -= 1
            cgraph[a].append((b, cost))
            cgraph[b].append((a, cost))
            tgraph[a].append((b, time))
            tgraph[b].append((a, time))
            
        c_dist = [shortestPath0(cgraph, s) for s in range(m)]
        t_dist = [shortestPath0(tgraph, s) for s in range(m)]

        k = int(input())
        for i in range(k):
            p, q, r = map(int, input().split())
            p-=1
            q-=1
            if r == 0:
                print(c_dist[p][q])
            else:
                print(t_dist[p][q])
main()

Python: # coding: utf-8
class Route:
    def __init__(self, next_station, need_price, need_time):
        self.next_station = next_station
        self.need_price = need_price
        self.need_time = need_time

class Station:
    def __init__(self):
        self.routes = []
    def addRoute(self,route):
        self.routes.append(route)

class Status:
    def __init__(self, now_station, use_price, use_time):
        self.now_station = now_station
        self.use_price = use_price
        self.use_time = use_time

def search(stations, start, end, search_type):
    result = [9999999999]
    queue = []
    for route in stations[start].routes:
        queue.append(Status(route.next_station, route.need_price, route.need_time))
    while len(queue) > 0:
        status = queue.pop(0)
        if status.now_station == end:
            r = status.use_price if search_type == 0 else status.use_time
            result.append(r)
        for route in stations[status.now_station].routes:
            update_price = route.need_price + status.use_price
            update_time = route.need_time + status.use_time
            queue.append(Status(route.next_station, update_price, update_time))
    print(sorted(result)[0])

route_count, station_count = map(int, input().split(" "))
stations = [Station() for station in range(station_count)]
for count in range(route_count):
    now_station, next_station, need_price, need_time = map(int, input().split(" "))
    stations[now_station - 1].addRoute(Route(next_station - 1, need_price, need_time))
search_count = int(input())
for count in range(search_count):
    start, end, search_type = map(int, input().split(" "))
    search(stations, start - 1, end - 1, search_type)

C++: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int > P;
const int INF = 1 << 30;
int Dijkstra(int s,int g,int r);

int m,n;

int min_cost[2][111];

typedef struct{
  vector<int>edge_to;
  vector<int>edge_cost[2];
}Node_data;

Node_data Graph[111];

priority_queue<P ,vector< P >, greater< P > >que;

int main(){
  int a,b,c,d,k;
  int s,g,r;
  while(1){
    cin >> m >> n;
    if(m == 0 && n == 0)break;
    for(int i = 0;i < m;i++){
      scanf("%d %d %d %d",&a,&b,&c,&d);
      Graph[a - 1].edge_to.push_back(b - 1);
      Graph[a - 1].edge_cost[0].push_back(c);
      Graph[a - 1].edge_cost[1].push_back(d);
      Graph[b - 1].edge_to.push_back(a - 1);
      Graph[b - 1].edge_cost[0].push_back(c);
      Graph[b - 1].edge_cost[1].push_back(d);
    }
    cin >> k;
    for(int i = 0;i < k;i++){

      cin >> s >> g >> r;

      for(int j = 0;j < n;j++){
	min_cost[r][j] = INF;
      }
      cout << Dijkstra(s - 1,g - 1,r) << endl;
    }
  }
  return(0);
}

int Dijkstra(int s,int g,int r){
  int node,cost;
  int newnode,newcost;
  min_cost[r][s] = 0;
  P a;
  a.first = 0;
  a.second = s;
  que.push(a);
  while(!que.empty()){
    node = que.top().second;
    cost = que.top().first;
    que.pop();
    if(node == g)return cost;
    if(cost > min_cost[r][node])continue;
    for(int i = 0;i < Graph[node].edge_to.size();i++){
      newnode = Graph[node].edge_to[i];
      newcost = min_cost[node] + Graph[node].edge_cost[r][i];
      if(min_cost[r][newnode] > newcost){
	min_cost[r][newnode] = newcost;
	a.first = newcost;
	a.second = newnode;
	que.push(a);
      }
    }
  }
  return -1;
}