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 }

 

posted @ 2012-04-13 11:05  笑巧  阅读(859)  评论(0编辑  收藏  举报