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]);

         

  • 相关阅读:
    golang删除数组某个元素
    golang用通道实现信号量,控制并发个数
    什么是ScaleIO中的forwards rebuild和backwards rebuild?
    SQL Server中的database checkpoint
    如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
    LoadTestAgentResultsLateException in VS2010
    SQL Server Instance无法启动了, 因为TempDB所在的分区没有了, 怎么办?
    VMware vCenter中, 如何辩认虚机上Raw Device Mapping过了的一块物理磁盘?
    SQL Server AlwaysOn Setup Step-By-Step Guide
    TPC-E在populate测试Database时需要注意的一些事项
  • 原文地址:https://www.cnblogs.com/windysai/p/3730923.html
Copyright © 2011-2022 走看看