zoukankan      html  css  js  c++  java
  • hdu 2544 最短路 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544

    题目意思:给出 n 个路口和 m 条路,每一条路需要 c 分钟走过。问从路口 1 到路口 n 需要的最短时间是多少。

          这题是最短路的入门题,从理解d-i--j---k(wg自创的,呵呵)到默打到修改,搞左两日终于好了,哈哈哈~~~太感动了。

         第一次错是 少了Dijkstra()函数中的 for (j = 1; j <= n; j++) 。

         第二次错是把vis[k=j]=1 写在了 if (!vis[j] && dist[j] < mini) 里面。

         好好总结自己的错误,以后应该能避免了。(做完郑多燕后,灵感翻来了,成日系实验室里对住堆恶心的实验报告兼做5成功,有种令人想死的感觉,忽略忽略)

         顺便帮大家普及下科学知识,经过我的搜罗,

       dijkstra /ˈdɛɪkstra/

          别读成 d  - i - j -k 了

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 #define INF 100000000
     8 const int maxn = 100 + 10;
     9 int dist[maxn], map[maxn][maxn], vis[maxn];
    10 int n, m;
    11 
    12 void Init()
    13 {
    14     int i, j, st, en, cost;
    15     for (i = 1; i <= n; i++)
    16         dist[i] = (i == 1 ? 0 : INF);
    17     memset(vis, 0, sizeof(vis));
    18     for (i = 1; i <= n; i++)
    19     {
    20         for (j = 1; j <= n; j++)
    21             map[i][j] = INF;  // 这样也行:map[i][j] = map[j][i] = (i == j ? 0 : INF);
    22     }
    23     for (i = 1; i <= m; i++)
    24     {
    25         scanf("%d%d%d", &st, &en, &cost);
    26         map[st][en] = map[en][st] = cost;   // 建立邻接矩阵
    27     }
    28 }
    29 
    30 void Dijkstra()
    31 {
    32     int i, j, k, mini;
    33     for (i = 1; i <= n; i++)
    34     {
    35         mini = INF;
    36         for (j = 1; j <= n; j++)   // 这个循环是用来找出与第i个点最近的点(当然是直接有边相连)
    37         {
    38             if (!vis[j] && dist[j] < mini)
    39             {
    40                 mini = dist[j];
    41                 k = j;
    42             }
    43         }
    44         vis[k] = 1;     // 如果把这句放在上面的if里面,就会把有些不该被标记已经过的点置1了,实质只需要置距离i点最短的那个点
    45         for (j = 1; j <= n; j++)
    46         {
    47             if (dist[j] > mini + map[k][j])   // mini其实就是dist[k],mini + map[k][j]表示绕过k点走到j点的路径会不会比直接不绕过k要短
    48                 dist[j] = mini + map[k][j];  // dist[j] = dist[k]+ map[k][j;
    49         }
    50     }
    51 }
    52 
    53 int main()
    54 {
    55     while(scanf("%d%d", &n, &m) && (m || n))
    56     {
    57         Init();
    58         Dijkstra();
    59         printf("%d
    ", dist[n]);
    60     }
    61     return 0;
    62 }

       

        邻接表 + 优先队列 + dijkstra (好强大,^_^)

        http://mindlee.net/2011/11/18/shortest-paths-algorithm/

        

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <climits>   // 定义各种数据类型最值得常量,如下面的INF_MAX: 2147483647
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int NV = 100 + 5;
      9 const int NE = 2e4 + 5;
     10 
     11 int n, m;
     12 
     13 struct Dijkstra
     14 {
     15     int n, size;
     16     int dis[NV], head[NV];
     17     int mark[NV];
     18 
     19     struct node
     20     {
     21         int v, dis;
     22         node() {}
     23         node(int V, int DIS): v(V), dis(DIS){}
     24         friend bool operator < (const node a, const node b)
     25         {
     26             return a.dis > b.dis;   // 结构体中,dis小的优先级高
     27         }
     28     };
     29 
     30     struct edge
     31     {
     32         int v, w, next;
     33         edge() {}
     34         edge(int V, int W, int NEXT): v(V), w(W), next(NEXT) {}
     35     }E[NE];
     36 
     37     inline void init(int vx)
     38     {
     39         n = vx, size = 0;
     40         memset(head, -1, sizeof(int)*(vx+1));
     41     }
     42 
     43     inline void insert(int u, int v, int w)
     44     {
     45         E[size] = edge(v, w, head[u]);  // E[size]. v = u, E[size].w = v, E[size].next = head[u]
     46         head[u] = size++;
     47     }
     48 
     49 /*    void print()  // 打印每个点的邻接表
     50     {
     51         for (int i = 0; i < n; i++)
     52         {
     53             printf("%d: ", i);
     54             for (int j = head[i]; j != -1; j = E[j].next)
     55             {
     56                 printf(" %d", E[j].v);
     57             }
     58             printf("
    ");
     59         }
     60     }
     61 */
     62     int dijkstra(int src, int des)   // src: 0  des: n-1
     63     {
     64         node first, next;
     65         priority_queue<node> Q;
     66         for (int i = 0; i <= n; i++)
     67         {
     68             dis[i] = INT_MAX;
     69             mark[i] = false;
     70         }
     71         dis[src] = 0;
     72         Q.push(node(src, 0));   // 把起始点入队
     73 
     74         while (!Q.empty())
     75         {
     76             first = Q.top();
     77             Q.pop();
     78             mark[first.v] = true;
     79 
     80             for (int i = head[first.v]; i != -1; i = E[i].next)
     81             {
     82                 if (!mark[E[i].v])
     83                 {
     84                     next = node(E[i].v, first.dis + E[i].w);
     85                     if (next.dis < dis[next.v])
     86                     {
     87                         dis[next.v] = next.dis;
     88                         Q.push(next);
     89                     }
     90                 }
     91             }      // end for
     92         }     // end while
     93         return dis[des];
     94     }     // end dijkstra
     95 }G;
     96 
     97 int main()
     98 {
     99     while (scanf("%d%d", &n, &m) != EOF && (m + n))
    100     {
    101         G.init(n);
    102         while (m--)
    103         {
    104             int u, v, w;
    105             scanf("%d%d%d", &u, &v, &w);
    106             G.insert(u-1, v-1, w);
    107             G.insert(v-1, u-1, w);
    108         }
    109     //    G.print();
    110         printf("%d
    ", G.dijkstra(0, n-1));
    111     }
    112     return 0;
    113 }

     Spfa + 邻接矩阵

        

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <queue>
     5 using namespace std;
     6 
     7 const int INF = 1e9;
     8 const int maxn = 100 + 5;
     9 int dist[maxn], map[maxn][maxn];
    10 bool mark[maxn];
    11 int N, M;
    12 
    13 int Spfa()
    14 {
    15     for (int i = 1; i <= N; i++)
    16     {
    17         mark[i] = false;
    18         dist[i] = INF;
    19     }
    20     queue<int> Q;
    21     dist[1] = 0;
    22     mark[1] = true;
    23     Q.push(1);
    24 
    25     while (!Q.empty())
    26     {
    27         int first = Q.front();
    28         Q.pop();
    29         mark[first] = false;
    30 
    31         for (int i = 1; i <= N; i++)
    32         {
    33             if (dist[first] + map[first][i] < dist[i])
    34             {
    35                 if (!mark[i])
    36                 {
    37                     Q.push(i);
    38                     mark[i] = true;    // mark 写在dist[i] 下一行也能过
    39                 }
    40                 dist[i] = dist[first] + map[first][i];
    41                 //  mark[i] = true;
    42             }
    43         }
    44     }
    45     return dist[N];
    46 }
    47 
    48 int main()
    49 {
    50     while (scanf("%d%d", &N, &M) != EOF && (N+M))
    51     {
    52         int A, B, C;
    53         for (int i = 1; i <= N; i++)
    54         {
    55             map[i][i] = INF;
    56             for (int j = i+1; j <= N; j++)
    57                 map[i][j] = map[j][i] = INF;    // 双向边!!!
    58         }
    59         while (M--)
    60         {
    61             scanf("%d%d%d", &A, &B, &C);
    62             map[A][B] = map[B][A] = C;
    63         }
    64         printf("%d
    ", Spfa());
    65     }
    66     return 0;
    67 }

         顺便写写:1874

        

    scanf("%d%d", &st, &en);    // st:起点  en:终点
    for (int i = 0; i < n; i++)
    {
    dist[i] = map[st][i];     // 构建起点到其他点之间的距离,INF代表不可达
    }

    输出注意下即可:printf("%d ", dist[en] == INF ? -1 : dist[en]);

         

  • 相关阅读:
    弹出新窗口
    网页布局之二 二列和三列
    JavaScript prototype
    window和linux开启动顺序
    ASP.net和javascript结合产生乱码的问题
    网页布局之一:XHTML CSS基础知识
    Study Android Chapter 1 Reading
    C++文件的读取
    心智模式
    各种排序算法的稳定性和时间复杂度小结
  • 原文地址:https://www.cnblogs.com/windysai/p/3730923.html
Copyright © 2011-2022 走看看