Go: // Warshall–Floyd Algorithm

package main

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

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
				} else {
					c_dist[i][j] = c_matrix[i][j]
				}
				if c_matrix[i][j] == 0{
					c_prev[i][j] = -1
				} else {
					c_prev[i][j] = i
				}
				if t_matrix[i][j] == 0{
					t_dist[i][j] = INF
				} else {
					t_dist[i][j] = t_matrix[i][j]
				}
				if t_matrix[i][j] == 0{
					t_prev[i][j] = -1
				} else {
					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]
					t_newlen := t_dist[i][k] + t_dist[k][j]
					if c_newlen < c_dist[i][j] {
						c_dist[i][j] = c_newlen
						c_prev[i][j] = c_prev[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])
			}
		}
	}
}

C++: #include <cstdio>
#include <vector>

using namespace std;

class Edge{
public:
	int from,to,cost,time;
	void Swap(){
		int self = from;
		from = to;
		to = from;
	}
	int GetValue(int r){
		if(r == 0){
			return cost;
		}else{
			return time;
		}
	}
};

vector<Edge> edge;
int n,m;

const int INF = 10000000;

int solve(const int p,const int q,const int r);

int main(){
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		Edge ed;
		scanf("%d %d %d %d",&ed.from,&ed.to,&ed.cost,&ed.time);
		edge.push_back(ed);
		ed.Swap();
		edge.push_back(ed);
	}
	int k;
	int p,q,r;
	scanf("%d",&k);
	for(int i=0;scanf("%d %d",&p,&q) && i < k;i++){
		if(p == 0 && q == 0){
			break;
		}
		scanf("%d",&r);
		printf("%d\n",solve(p,q,r));
	}
	return 0;
}

int solve(const int p,const int q,const int r){
	//vector<int> d(m+1);
	int *d = new int[100+1];
	for(int i=0;i<=100;i++){
		d[i] = INF;
	}
	d[p] = 0;
	
	bool flag;
	while(1){
		flag = false;
		vector<Edge>::iterator it;
		for(it = edge.begin();it != edge.end();it++){
			if(d[(*it).from] != INF && d[(*it).to] > d[(*it).from] + (*it).GetValue(r)){
				d[(*it).to] = d[(*it).from] + (*it).GetValue(r);
				flag = true;
			}
		}
		if(!flag){
			break;
		}
	}
	
	int ans = d[q];
	delete [] d;
	return ans;
}

C++: #include<iostream>
#include<stdio.h>
using namespace std ;

int n , m ;
int data[101][101][2] ;

void f(){
	for( int k=1 ; k<=m ; k++ ){
		for( int i=1 ; i<=m ; i++ ){
			for( int j=1 ; j<=m ; j++ ){
				if( data[i][j][0] > data[i][k][0] + data[k][j][0] ){
					data[i][j][0] = data[i][k][0] + data[k][j][0] ;
				}
				if( data[i][j][1] > data[i][k][1] + data[k][j][1] ){
					data[i][j][1] = data[i][k][1] + data[k][j][1] ;
				}
			}
		}
	}
}

int main(){
	
	int a , b ;
	int k , r ;
	
	while(1){
		cin >> n >> m ;
		if( n==0 && m==0 ) break ;
		
		for( int i=0 ; i<101 ; i++ ){
			for( int j=0 ; j<101 ; j++ ){
				data[i][j][0] = 100000000 ;
				data[i][j][1] = 100000000 ;
			}
			data[i][i][0] = 0 ;
			data[i][i][1] = 0 ;
		}
		
		for( int i=0 ; i<n ; i++ ){
			cin >> a >> b ;
			cin >> data[a][b][0] >> data[a][b][1] ;
			data[b][a][0] = data[a][b][0] ;
			data[b][a][1] = data[a][b][1] ;
		}
		
		f() ;
		
		/*for( int i=1 ; i<m ; i++ ){
			for( int j=1 ; j<m ; j++ ){
				printf("data[%d][%d][0] = %d\n" ,i ,j ,data[i][j][0] ) ;
				printf("data[%d][%d][1] = %d\n" ,i ,j ,data[i][j][1] ) ;
			}
		}*/
		
		cin >> k ;
		//cout << "k=" << k << endl ;
		
		for( int i=0 ; i<k ; i++ ){
			cin >> a >> b >> r ;
			cout << data[a][b][r] << endl ;
		}
	}
	
return 0 ;
}

C++: #include<iostream>
#include<queue>
#include<vector>
#include<limits>

using namespace std;

struct RequestObj {
	int begin, end, type;
};

int n, m;//???,???????????°
int k;//????????¨????????°
int time_table[100][100];
int cheap_table[100][100];
RequestObj request[200];

const int INF = 100000000;

int main() {
	while (cin >> n >> m, n * m) {
		for (int i = 0; i < 100; i++)for (int j = 0; j < 100; j++)time_table[i][j] = INF, cheap_table[i][j] = INF;

		for (int i = 0; i < n; i++) {
			int a, b;
			cin >> a >> b;
			cin >> cheap_table[a - 1][b - 1] >> time_table[a - 1][b - 1];
		}
		cin >> k;
		for (int i = 0; i < k; i++) {
			cin >> request[i].begin >> request[i].end >> request[i].type;
		}
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				for (int k = 0; k < m; k++) {
					if (cheap_table[j][i] + cheap_table[i][k] < cheap_table[j][k]) {
						cheap_table[j][k] = cheap_table[j][i] + cheap_table[i][k];
					}
				}
			}
		}

		for (int i = 0; i < m; i++) {
			for (int j = 0; j < m; j++) {
				for (int k = 0; k < m; k++) {
					if (time_table[j][i] + time_table[i][k] < time_table[j][k]) {
						time_table[j][k] = time_table[j][i] + time_table[i][k];
					}
				}
			}
		}
		for (int i = 0; i < k; i++) {
			if (request[i].type == 0) {
				cout << cheap_table[request[i].begin - 1][request[i].end - 1] << endl;
			}
			else {
				cout << time_table[request[i].begin - 1][request[i].end - 1] << endl;
			}
		}
	}
	return 0;
}

C++: #include <list>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
#define INF (1LL << 60)
using namespace std;
bool used[100]; long long dist[100];
void dijkstra(int V, int E, int s, vector<pair<int, long long> > X[]) {
	priority_queue<pair<long long, int>, vector<pair<long long, int> >, greater<pair<long long, int> > > Q;
	for (int i = 0; i < V; i++) dist[i] = INF, used[i] = false;
	dist[s] = 0; Q.push(make_pair(0, s));
	int cnt = 0;
	while (!Q.empty()) {
		if (cnt > E) return; // NEGATIVE_CYCLE
		pair<long long, int> p = Q.top(); used[p.second] = true; Q.pop();
		for (int i = 0; i < X[p.second].size(); i++) {
			int to = X[p.second][i].first; long long leng = X[p.second][i].second;
			if (dist[to] > dist[p.second] + leng && !used[to]) {
				dist[to] = dist[p.second] + leng;
				Q.push(make_pair(dist[to], to));
			}
		}
	}
}
int n, m, q, a, b, c, u, v, w1, w2; vector<pair<int, long long> > G1[100], G2[100];
int main() {
	while(cin >> n >> m, n) {
		for(int i = 0; i < m; i++) G1[i].clear(), G2[i].clear();
		for(int i = 0; i < n; i++) {
			cin >> u >> v >> w1 >> w2; u--, v--;
			G1[u].push_back(make_pair(v, w1));
			G1[v].push_back(make_pair(u, w1));
			G2[u].push_back(make_pair(v, w2));
			G2[v].push_back(make_pair(u, w2));
		}
		cin >> q;
		for(int i = 0; i < q; i++) {
			cin >> a >> b >> c; a--, b--;
			if(c == 0) {
				dijkstra(m, n, a, G1);
				cout << dist[b] << endl;
			}
			else {
				dijkstra(m, n, a, G2);
				cout << dist[b] << endl;
			}
		}
	}
}