HDU3790(最短路径)
题意:给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
解题思路:这是最短路问题的变形,以前做的只是求两点之间的最短距离,现在除了距离最短,在此基础上增加了花费最少。用弗洛伊德算法同样可以求解。
注意:输入时要考虑重边情况。由于0<n<=1000,0<m<100000,开二维数组也不小,用C++提交超时,把输入输出改用scanf和printf 就AC了。
View Code
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5
6 #define MAX 0xfffffff
7 int map[1005][1005],money[1005][1005];
8 int dis[1005],pri[1005],sign[1005];
9 int main()
10 {
11 int n,m,i,a,b,d,p,s,t;
12 while(scanf("%d%d",&n,&m))
13 {
14 if(n==0&&m==0) break;
15 memset(map,-1,sizeof(map));
16 memset(sign,0,sizeof(sign));
17 while(m--)
18 {
19 scanf("%d%d%d%d",&a,&b,&d,&p);
20 if(map[a][b]==-1||map[a][b]>d)
21 {
22 map[a][b]=map[b][a]=d;
23 money[a][b]=money[b][a]=p;
24 }
25 else if(map[a][b]==d&&money[a][b]>p)
26 money[a][b]=money[b][a]=p;
27 }
28 scanf("%d%d",&s,&t);
29 for(i=1;i<=n;i++)
30 {
31 dis[i]=map[s][i];
32 pri[i]=money[s][i];
33 }
34 sign[s]=1;
35 dis[s]=pri[s]=0;
36 int dmin,pmin,u;
37 while(1)
38 {
39 dmin=pmin=MAX;
40 for(i=1;i<=n;i++)
41 if(!sign[i]&&dis[i]>0)
42 {
43 if(dis[i]<dmin) { u=i; dmin=dis[u]; }
44 else if(dis[i]==dmin&&pri[i]<pmin) { u=i; pmin=pri[u]; }
45 }
46 sign[u]=1;
47 if(u==t) break;
48 for(i=1;i<=n;i++)
49 if(!sign[i]&&map[u][i]>0)
50 {
51 if(dis[i]==-1||dis[u]+map[u][i]<dis[i])
52 {
53 dis[i]=dis[u]+map[u][i];
54 pri[i]=pri[u]+money[u][i];
55 }
56 else if(dis[u]+map[u][i]==dis[i]&&pri[u]+money[u][i]<pri[i])
57 pri[i]=pri[u]+money[u][i];
58 }
59 }
60 printf("%d %d\n",dis[t],pri[t]);
61 }
62 return 0;
63 }
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5
6 #define MAX 0xfffffff
7 int map[1005][1005],money[1005][1005];
8 int dis[1005],pri[1005],sign[1005];
9 int main()
10 {
11 int n,m,i,a,b,d,p,s,t;
12 while(scanf("%d%d",&n,&m))
13 {
14 if(n==0&&m==0) break;
15 memset(map,-1,sizeof(map));
16 memset(sign,0,sizeof(sign));
17 while(m--)
18 {
19 scanf("%d%d%d%d",&a,&b,&d,&p);
20 if(map[a][b]==-1||map[a][b]>d)
21 {
22 map[a][b]=map[b][a]=d;
23 money[a][b]=money[b][a]=p;
24 }
25 else if(map[a][b]==d&&money[a][b]>p)
26 money[a][b]=money[b][a]=p;
27 }
28 scanf("%d%d",&s,&t);
29 for(i=1;i<=n;i++)
30 {
31 dis[i]=map[s][i];
32 pri[i]=money[s][i];
33 }
34 sign[s]=1;
35 dis[s]=pri[s]=0;
36 int dmin,pmin,u;
37 while(1)
38 {
39 dmin=pmin=MAX;
40 for(i=1;i<=n;i++)
41 if(!sign[i]&&dis[i]>0)
42 {
43 if(dis[i]<dmin) { u=i; dmin=dis[u]; }
44 else if(dis[i]==dmin&&pri[i]<pmin) { u=i; pmin=pri[u]; }
45 }
46 sign[u]=1;
47 if(u==t) break;
48 for(i=1;i<=n;i++)
49 if(!sign[i]&&map[u][i]>0)
50 {
51 if(dis[i]==-1||dis[u]+map[u][i]<dis[i])
52 {
53 dis[i]=dis[u]+map[u][i];
54 pri[i]=pri[u]+money[u][i];
55 }
56 else if(dis[u]+map[u][i]==dis[i]&&pri[u]+money[u][i]<pri[i])
57 pri[i]=pri[u]+money[u][i];
58 }
59 }
60 printf("%d %d\n",dis[t],pri[t]);
61 }
62 return 0;
63 }