题目:http://acm.hdu.edu.cn/showproblem.php?pid=3790
和普通的最短路径相比,这里要多计算相同最短路径下的最小费用,所以再增加一个数组,在Dijkstra里也做一点改动,让费用数组跟着变化。
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
const int INF=0x3f3f3f3f;
int map[1005][1005],cost[1005][1005],dis[1005],spe[1005];
void inital(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cost[i][j]=INF;
map[i][j]=INF;
}
}
}
void Dijkstra(int s,int t){
bool tag[1005];
memset(tag,0,sizeof(tag));
memset(dis,0,sizeof(dis));
memset(spe,0,sizeof(spe));
tag[s]=1;
dis[s]=0;
for(int i=1;i<=n;i++){ dis[i]=map[s][i]; spe[i]=cost[s][i]; }
for(int i=1;i<n;i++){
int k=0,mmin=INF,minsp=INF;
for(int j=1;j<=n;j++){
if(!tag[j]&&mmin>dis[j]){
mmin=dis[j];
minsp=spe[j];
k=j;
}
}
if(k==0)return ;
tag[k]=1;
for(int j=1;j<=n;j++){
if(!tag[j]&&map[k][j]!=INF){
if(dis[j]>mmin+map[k][j]){ //spe跟着变
dis[j]=mmin+map[k][j];
spe[j]=minsp+cost[k][j];
}
else if(dis[j]==mmin+map[k][j]&&spe[j]>minsp+cost[k][j]){
spe[j]=minsp+cost[k][j];
}
}
}
}
}
int main()
{
//freopen("cin.txt","r",stdin);
int m,i,j,s,t;
while(cin>>n>>m){
if(n==0&&m==0)break;
inital();
for(i=0;i<m;i++){
int a,b,d,p;
scanf("%d%d%d%d",&a,&b,&d,&p);
if(map[a][b]==d&&cost[a][b]>p){ //担心又有奇葩数据~
cost[a][b]=p;
cost[b][a]=p;
}
else if(map[a][b]>d){
map[a][b]=d; map[b][a]=d;
cost[a][b]=p; cost[b][a]=p;
}
}
scanf("%d%d",&s,&t);
Dijkstra(s,t);
printf("%d %d\n",dis[t],spe[t]);
}
return 0;
}