3 2 1 2 5 6 2 3 4 5 1 3 0 0
9 11
这题要注意两点,第一个是可能会存在重边,当两点之间存在重边的时候,存储长度最短的那条,如果有多条最短边,则取费用最低的那条边;第二个是最大值MAX的设置,一开始我设置的是INT_MAX,结果一直WA,因为INT_MAX与其他正值相加后会溢出成为负值,使得判定条件出错,这个一定要多加小心。
源代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1001;
const int MAX = 1 << 30;
int dm[N][N];
int pm[N][N];
int minDis, minCost;
void dijkstra(int s, int t, int n);
int main(){
	int n, m;
	while(cin >> n >> m){
		if(n==0 && m==0) break;
		//初始化距离矩阵和费用矩阵
		for(int i=1; i<=n; i++){
			for(int j=1; j<=n; j++){
				dm[i][j] = MAX;
				pm[i][j] = MAX;
			}
		}
		for(int i=0; i<m; i++){
			int a, b, d, p;
			cin >> a >> b >> d >> p;
			//这两个判断条件是为了处理重边
			if(dm[a][b] > d){
				dm[a][b] = dm[b][a] = d;
				pm[a][b] = pm[b][a] = p;
			}
			else if(dm[a][b]==d && pm[a][b]>p){
				pm[a][b] = pm[b][a] = p;
			}
		}
		int s, t;
		cin >> s >> t;
		dijkstra(s, t, n);
		cout << minDis << ‘ ‘ << minCost << endl;
	}
	
	//system("pause");
	return 0;
}
void dijkstra(int s, int t, int n){
	//存储点s到各点的距离和费用
	int dis[N];
	int cost[N];
	for(int i=1; i<=n; i++){
		dis[i] = MAX;
		cost[i] = MAX;
	}
	//用于判断是否已经求出s点到某点的最短距离和费用
	bool visit[N];
	memset(visit, false, sizeof(visit));
	//点s到自己的距离和费用为0
	dis[s] = 0;
	cost[s] = 0;
	for(int i=0; i<n; i++){
		int min = MAX;
		int k;
		for(int j=1; j<=n; j++){
			if(!visit[j] && dis[j]<min){
				min = dis[j];
				k = j;
			}
		}
		visit[k] = true;
		for(int j=1; j<=n; j++){
			if(!visit[j] && dis[j]>min+dm[k][j]){
				dis[j] = min + dm[k][j];
				cost[j] = cost[k] + pm[k][j];
			}
			else if(!visit[j] && dis[j]==min+dm[k][j] && cost[j]>cost[k]+pm[k][j]){
				cost[j] = cost[k] + pm[k][j];
			}
		}
	}
	minDis = dis[t];
	minCost = cost[t];
}
原文:http://www.cnblogs.com/chaos---/p/6523411.html