HDU 1385 Minimum Transport Cost Floyd算法

http://acm.hdu.edu.cn/showproblem.php?pid=1385

题意:

  输入一个N*N的矩阵,(x,y)代表城市x到城市y所花费的钱,后面有一行b1,b2......bn代表经过城市n所需的费用,后面是几组问题(a,b) 

也就是要你计算出a到b的最少花费的费用(a、b不收费),并且要输出路径。

 

坑爹:

  要求输出最小的那一组解 ,也就是说当 1-2-3-4 和1-5-3-4花费的费用是相同的时候要输出1-2-3-4。

 

解法:

  路径用一个path数组,初始化将path[i][j] = j ,在Floyd中只要满足map[i][j] > map[i][k] + map[k][j] ,就执行 path[i][j] = path[i][k] ,

这样就代表从 i 点出发的沿最短路径走向 j 的第一个点。例如:1-2-3-4    path[1][4] == 2 , path[2][4] == 3 , path[3][4] == 4 。

 

View Code
  1 #include<iostream>
  2 #include<stack>
  3 using namespace std;
  4 
  5 const int maxn = 10000 + 10;
  6 const int INF = 0x3fffffff;
  7 int map[maxn][maxn];
  8 int B[maxn];
  9 int path[maxn][maxn];
 10 int N;
 11 
 12 /*
 13 void init()
 14 {
 15     int i;
 16     int j;
 17     for(i=1; i<=N; i++)
 18     {
 19         for(j=1; j<=N; j++)
 20         {
 21             if(i==j)
 22             {
 23                 map[i][j]=0;
 24             }
 25             else
 26             {
 27                 map[i][j]=INF;
 28             }
 29         }
 30     }
 31 }
 32 */
 33 void floyd()
 34 {
 35     int i;
 36     int j;
 37     int k;
 38     for(k=1; k<=N; k++)
 39     {
 40         for(i=1; i<=N; i++)
 41         {    
 42             for(j=1; j<=N; j++)
 43             {
 44                 if(i==k || map[i][k] == -1)
 45                 {
 46                     break;
 47                 }
 48                 if(i==j || j==k || map[k][j]==-1)
 49                 {
 50                     continue;
 51                 }
 52                 if(map[i][j]>map[i][k]+map[k][j]+B[k] || map[i][j]==-1)
 53                 {
 54                     path[i][j]=path[i][k];
 55                     map[i][j]=map[i][k]+map[k][j]+B[k];
 56                 }
 57                 else if(map[i][j]==map[i][k]+map[k][j]+B[k] && path[i][j]>path[i][k])
 58                 {
 59                     path[i][j]=path[i][k];
 60                 }
 61             }
 62         }
 63     }
 64 }
 65 
 66 int main()
 67 {
 68     while(cin>>N,N)
 69     {
 70         int i;
 71         int j;
 72         for(i=1; i<=N; i++)
 73         {
 74             for(j=1; j<=N; j++)
 75             {
 76                 cin>>map[i][j];
 77                 path[i][j]=j;
 78             }
 79         }
 80         
 81         for(i=1; i<=N; i++)
 82         {
 83             cin>>B[i];
 84         }
 85         
 86         floyd();
 87         
 88         int x;
 89         int y;
 90         while(cin>>x>>y && x!=-1 && y!=-1)
 91         {    
 92             printf("From %d to %d :\n",x,y);
 93             printf("Path:");
 94             if(x!=y)
 95             {
 96                 printf(" %d-->",x);
 97                 int k=x;
 98                 while(path[k][y]!=y)
 99                 {
100                     printf("%d-->",path[k][y]);
101                     k=path[k][y];
102                 }    
103                 printf("%d\n",y);
104                 printf("Total cost : %d\n",map[x][y]);
105             }
106             else
107             {
108                 printf(" %d\n",y);
109                 printf("Total cost : 0\n");
110             }
111             printf("\n");
112         }
113     }
114     return 0;
115 }

 

转载于:https://www.cnblogs.com/pcpcpc/archive/2012/09/04/2670565.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值