Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=1<<31-1; 6 int map[1004][1004][2]; 7 int v[1004],s1[1004],s2[1004]; 8 int n; 9 void dijk(int x) 10 { 11 v[x]=1; 12 int i; 13 for (i=1;i<=n;i++) 14 { 15 s1[i]=map[i][x][0]; 16 s2[i]=map[i][x][1]; 17 } 18 while (1) 19 { 20 int m1=N,m2=N,p=x; 21 for (i=1;i<=n;i++) 22 { 23 if (v[i]) continue; 24 if (m1>s1[i]) 25 { 26 m1=s1[i]; 27 m2=s2[i]; 28 p=i; 29 } 30 else if (m1==s1[i]&&m2<s2[i]) 31 { 32 m2=s2[i]; 33 p=i; 34 } 35 } 36 if (p==x) break; 37 v[p]=1; 38 for (i=1;i<=n;i++) 39 { 40 if (v[i]) continue; 41 if (s1[i]>s1[p]+map[p][i][0]) 42 { 43 s1[i]=s1[p]+map[p][i][0]; 44 s2[i]=s2[p]+map[p][i][1]; 45 } 46 else if (s1[i]==s1[p]+map[p][i][0]&&s2[i]>s2[p]+map[p][i][1]) 47 s2[i]=s2[p]+map[p][i][1]; 48 } 49 } 50 } 51 int main() 52 { 53 int m,i,j,a,b,c,d; 54 while (~scanf("%d%d",&n,&m)) 55 { 56 if (n==0&&m==0) break; 57 for (i=1;i<=n;i++) 58 for (j=1;j<=n;j++) 59 { 60 map[i][j][0]=N; 61 map[i][j][1]=N; 62 } 63 for (i=1;i<=m;i++) 64 { 65 scanf("%d%d%d%d",&a,&b,&c,&d); 66 if (map[a][b][0]>c) 67 { 68 map[a][b][0]=map[b][a][0]=c; 69 map[a][b][1]=map[b][a][1]=d; 70 } 71 else if (map[a][b][0]==c&&map[a][b][0]>d) 72 { 73 map[a][b][0]=map[b][a][0]=c; 74 map[a][b][1]=map[b][a][1]=d; 75 } 76 } 77 memset(v,0,sizeof(v)); 78 scanf("%d%d",&a,&b); 79 dijk(a); 80 printf("%d %d ",s1[b],s2[b]); 81 } 82 }