题目链接: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;
}