• 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 }
  • 相关阅读:
    实验4
    实验3
    第七章例7-14
    第七章例7-13
    第七章例7-12
    第七章例7-11
    第七章例7-10
    diyiti
    disanti
    第二题
  • 原文地址:https://www.cnblogs.com/JZQT/p/3802441.html
Copyright © 2020-2023  润新知