hdu1385 Minimum Transport Cost

昨天晚上做这个题目到1点钟也没有发现错误,后来火大,果断重新开始写,今天下午终于AC。。算法为floyd+dfs,先使用floyd求出最短路,然后从起点开始深搜到终点并且记录路径,由于i从1开始遍历,因此所找到的第一条最短路路即为字典序最小路径,需要注意一下终点没有税,而且只需要输出字典序最小的那一条路。

AC代码如下:

#include <iostream>

using namespace std;

const int len = 110;

#define  MAX1  0xfffffff

int dis[len][len];

int map[len][len];

int tax[len];

int path[len];

int visited[len];

int S, E;

int size;

int n;

void Floyd()

{

     int i, j, k;

     for (k = 1; k <= n; k ++){

         for (i = 1; i <= n; i ++){

             for (j = 1; j <= n; j ++){

                 if (dis[i][k]+dis[k][j]+tax[k] < dis[i][j]){

                    dis[i][j] = dis[i][k]+dis[k][j]+tax[k];             

                 }    

             }    

         }    

     }     

}

int check;

void Dfs(int deep, int sum)

{

     if (sum > dis[S][E])return ;

     if (sum == dis[S][E] && deep == E){

        printf("Path: %d", S);

        for (int i = 0; i < size; i ++){

            printf("-->%d", path[i]);   

        }

        printf("/n");

        check = 1;

        return ;      

     }         

     for (int i = 1; i <= n; i ++){

         if (!visited[i]){

            if (map[deep][i] != MAX1){

               visited[i] = 1;

               sum += map[deep][i];

               if (i != E){

                  sum += tax[i];      

               }

               path[size ++] = i;

               Dfs(i, sum);

               size --;

               if (check)return ; 

               visited[i] = 0;

               sum -= map[deep][i];

               if (i != E){

                  sum -= tax[i];      

               }                 

            }                 

         }         

     }

}

int main()

{

 

    while ( scanf("%d", &n) && n){

          for (int i = 1; i <= n; i ++){

              for (int j = 1; j <= n; j ++){

                   scanf("%d", &map[i][j]);

                  if (map[i][j] == -1){

                     map[i][j] = MAX1;              

                  }

                  dis[i][j] = map[i][j];    

              }    

          }

          for (int i = 1; i <= n; i ++){

              scanf("%d", &tax[i]);    

          }

          Floyd();

          while (scanf("%d %d", &S, &E)&& S+E != -2){

                check = 0;

                printf("From %d to %d :/n", S, E);

                memset(visited, 0, sizeof(visited));

                Dfs(S, 0);

                printf("Total cost : %d/n/n", dis[S][E]);

          }      

    }

    return 0;    

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值