题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790
#include <iostream> #include <stdio.h> #include <string.h> #define MAX 10000005 #define N 1005 using namespace std; /**************************************************************************************************************** 题意:在最短路径的基础上,输出花费最小的那个路径 思路: 1,dijkstra找最短路径 2,在每次更新路径长度的同时更新花费即可 ****************************************************************************************************************/ int visit[N]; //用来判断是非在特殊路径集合点内 int dist[N],cost[N]; int a[N][N],V[N][N]; int dijkstra(int start,int End,int n) { for(int i = 1;i <= n;i ++){ dist[i]=a[start][i]; cost[i]=V[start][i]; } memset(visit,0,sizeof(visit)); dist[start]=0; //cost[start]=0; visit[start]=1; for(int i = 1;i < n;i ++){ int id=1,ansN=MAX; for(int j = 1;j <= n;j ++){ if(!visit[j] && dist[j] < ansN){ //在S集合外找出最小路径点(即非特殊路径) ansN=dist[j]; id=j; } } visit[id]=1; for(int j = 1;j <= n;j ++){ //以找到的最小路径点为最优解进行动态更新(非特殊路径集合点内遍历) if(!visit[j] && a[id][j] < MAX){ if(dist[j] > dist[id]+a[id][j]){ dist[j]=dist[id]+a[id][j]; cost[j]=cost[id]+V[id][j]; //更新花费 } else if(dist[j] == dist[id]+a[id][j]){ if(cost[j] > cost[id]+V[id][j]) cost[j]=cost[id]+V[id][j]; //更新花费 } } } //if(id == End) return 0; } } int main() { int n,m; while(scanf("%d%d",&n,&m) != EOF) { if(n == 0 && m == 0) break; for(int i = 1;i <= n;i ++){ for(int j = 1;j <= n;j ++){ a[i][j]=MAX; V[i][j]=MAX; } dist[i]=MAX; cost[i]=MAX; } //memset(dist,MAX,sizeof(dist)); int A,B,C,D; for(int i = 1;i <= m;i ++){ scanf("%d%d%d%d",&A,&B,&C,&D); if(C < a[A][B]){ a[A][B]=a[B][A]=C; V[A][B]=V[B][A]=D; } else if(C == a[A][B]){ if(D < V[A][B]) V[A][B]=V[B][A]=D; } } int Start,End; cin>>Start>>End; dijkstra(Start,End,n); cout<<dist[End]<<" "<<cost[End]<<endl; } return 0; }