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 }

 

你可能感兴趣的:(最短路径)