用Dijsktra,考虑重边的情况。
#include <iostream> #include<queue> #include<stdio.h> #include<cstring> using namespace std; typedef struct{ int di,p;}road; road w[1005][1005],d[1005]; int visit[1005]; const int INF=100000000; int main() { int n,m,i,j,s,e,ok,temp_1,temp_2,dis,pa,re; while(scanf("%d %d",&n,&m)){ if(n+m==0) break; memset(visit,0,sizeof(visit)); for(i=1;i<=n;i++) for(j=1;j<=n;j++){ w[i][j].di=INF; w[i][j].p=INF; } for(i=1;i<=m;i++){ scanf("%d %d %d %d",&temp_1,&temp_2,&dis,&pa); if(w[temp_1][temp_2].di>dis) { w[temp_1][temp_2].di=w[temp_2][temp_1].di=dis; w[temp_1][temp_2].p=w[temp_2][temp_1].p=pa; } else if(w[temp_1][temp_2].di==dis) if(w[temp_1][temp_2].p>pa) w[temp_1][temp_2].p=w[temp_2][temp_1].p=pa; } /*注意这里不能合并写成if{(距离>=输入值)if(花费>输入值)更改花费} eg:原来路径 时间值为3 2,若读入一组2 4,那么就会更新为2 2,但正确的应该是更新为2 4*/ scanf("%d %d",&s,&e); for(i=1;i<=n;i++){ d[i].di=(i==s?0:INF); d[i].p=(i==s?0:INF); } queue<int>q; q.push(s); visit[s]=1; while(!q.empty()){ int temp=q.front(); q.pop(); int min=INF; ok=0; for(i=1;i<=n;i++){ if(visit[i]==0&&i!=temp){ if(d[i].di>d[temp].di+w[temp][i].di){ d[i].di=d[temp].di+w[temp][i].di; d[i].p=d[temp].p+w[temp][i].p; } else if(d[i].di==d[temp].di+w[temp][i].di) if(d[i].p>d[temp].p+w[i][temp].p) d[i].p=d[temp].p+w[temp][i].p; if(d[i].di<min){ re=i; min=d[i].di; ok=1; } } } if(ok==1){ q.push(re); visit[re]=1; } } printf("%d %d\n",d[e].di,d[e].p); } return 0; }