HDOJ-2680-Choose the best route 解题报告

       这是一道不错的最短路题目,半水不水的题,还是需要动脑思考一下的。题意:琪琪想要去拜访她的朋友,但是这货容易晕车,所以要找一个花费时间最少的路线。现在给你路线图,让你找出从她家附近的起点站(可以有多个)到朋友家附近的终点站(只有一个)花费时间最少的路线。各个站点的编号从1到n。


       我的解题思路:首先是输入站点数量,路线数量(在两个站点之间可以有多条路线)和终点;然后是各个路线的信息(起点终点以及耗时);最后再输入起点的个数和起点。由于站点数量最多可以达到1000,因此Floyd算法是不行的了(事实上我一开始就用这个写,TLE了)。我们换个思路,用Dijkstra啊!有几个起点就用几次Dijkstra。恩,这么做是没什么错,只要起点的数量不是很接近站点的数量,那么多多少少的确有所优化(没用此方法提交过)。但是我们可以有一种更加精明的解法啊,那就是把终点看做起点,起点看做终点,这样的话用一次Dijkstra就可以了,省时省力有省心啊有木有。可见,多思考一下别的解法还是有用的。


       注意:本题为单向图。那么,起点看做终点,终点看做起点时要进行反向构图。


       接下来是我的解题代码:Dijkstra解法

  1 #include <stdio.h>
  2 #define N 1001
  3 #define INF 999999
  4 
  5 int map[N][N];
  6 int dis[N];     //在本题中代表从终点s到编号为下标的点的时间
  7 int flag[N];    //标志变量
  8 int n, m, s;
  9 
 10 void Init();    //初始化
 11 
 12 void Read();    //图信息的输入
 13 
 14 void Dijkstra();
 15 
 16 void DataProcess();     //起点的输入以及答案的计算
 17 
 18 int main()
 19 {
 20     while (~scanf("%d %d %d", &n, &m, &s))
 21     {
 22         Init();
 23         Read();
 24         Dijkstra();
 25         DataProcess();
 26     }
 27     return 0;
 28 }
 29 
 30 void Init()     //初始化
 31 {
 32     int i, j;
 33     for (i=1; i<=n; ++i)
 34     {
 35         for (j=1; j<=n; ++j)
 36         {
 37             map[i][j] = i == j ? 0 : INF;
 38         }
 39         dis[i] = INF;
 40         flag[i] = 0;
 41     }
 42     return;
 43 }
 44 
 45 void Read()     //图信息的输入
 46 {
 47     int i;
 48     int a, b, c;
 49     for (i=0; i<m; ++i)
 50     {
 51         scanf("%d %d %d", &a, &b, &c);
 52         if (map[b][a] > c)      //处理重边问题
 53         {
 54             map[b][a] = c;      //反向构图
 55         }
 56     }
 57     return;
 58 }
 59 
 60 void Dijkstra()
 61 {
 62     int i, j, k;
 63     int min;
 64     dis[s] = 0;     //设终点为起点
 65     for (i=1; i<=n; ++i)
 66     {
 67         min = INF;
 68         for (j=1; j<=n; ++j)
 69         {
 70             if (flag[j] == 0 && dis[j] < min)
 71             {
 72                 min = dis[k = j];
 73             }
 74         }
 75         flag[k] = 1;
 76         for (j=1; j<=n; ++j)
 77         {
 78             if (flag[j] == 0 && dis[j] > dis[k] + map[k][j])
 79             {
 80                 dis[j] = dis[k] + map[k][j];
 81             }
 82         }
 83     }
 84     return;
 85 }
 86 
 87 void DataProcess()      //起点的输入以及答案的计算
 88 {
 89     int i, w, x;
 90     int ans = INF;
 91     scanf("%d", &w);
 92     for (i=0; i<w; ++i)
 93     {
 94         scanf("%d", &x);
 95         if (ans > dis[x])
 96         {
 97             ans = dis[x];
 98         }
 99     }
100     printf("%d
", ans == INF ? -1 : ans);
101     return;
102 }
原文地址:https://www.cnblogs.com/JZQT/p/3802441.html