zoukankan      html  css  js  c++  java
  • 图论 最短路专辑

    先上总结构图

    1 首先来看Dijkstra

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <memory.h>
     4 
     5 
     6 using namespace std;
     7 
     8 const int N = 550;
     9 int n , m ;
    10 int g[N][N];
    11 int dist[N];
    12 bool st[N];
    13 
    14 
    15 int dijkstra()
    16 {
    17    memset(dist,0x3f,sizeof(dist));
    18    dist[1] = 0;
    19    
    20    for(int i = 0; i < n ; i++)
    21    {
    22        int t = -1;
    23        for(int j = 1;j <= n;j++){
    24             if( !st[j] && (t == -1|| dist[t]  > dist[j]))
    25                 t = j;      //更换为更小的dist
    26        }
    27        
    28        st[t] = true;
    29        
    30        //用t来更新其他点的dist
    31        for(int j = 1; j <= n;j++){
    32            dist[j] = min(dist[j],dist[t]+g[t][j]);
    33        }
    34    }
    35     
    36     if(dist[n] == 0x3f3f3f3f)  
    37         return -1;
    38     
    39     return dist[n];
    40 }
    41 
    42 /*
    43 int main(){
    44     scanf("%d %d",&n,&m);
    45     
    46     memset(g,0x3f,sizeof(g));
    47     
    48     while(m--){
    49         int a,b,c;
    50         cin >> a >>b>>c;
    51         g[a][b] = min(g[a][b],c);
    52     }
    53     
    54     int t = dijkstra();
    55     
    56     cout<< t << endl;
    57     
    58     
    59     
    60     return 0;
    61 }
    62 */
    63 int main()
    64 {
    65     scanf("%d%d", &n, &m);
    66 
    67     memset(g, 0x3f, sizeof g);
    68     while (m -- )
    69     {
    70         int a, b, c;
    71         scanf("%d%d%d", &a, &b, &c);
    72 
    73         g[a][b] = min(g[a][b], c);
    74     }
    75 
    76     printf("%d
    ", dijkstra());
    77 
    78     return 0;
    79 }
    acwing 849

    2 bellman_ford

     优势在于 可以求出使用K次边的情况下的最短路径 

     1 #include <cstring>
     2 #include <iostream>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 
     8 const int N = 510; 
     9 const int M = 10010;
    10 
    11 int n,m,k;
    12 int dist[N],backup[N];
    13 
    14 struct Edge{
    15     int a, b,w;
    16 }edges[M];
    17 
    18 int bellman_ford()
    19 {
    20     memset(dist,0x3f,sizeof(dist));
    21     dist[1] = 0; 
    22     
    23     for(int i = 0; i < k;i ++){
    24         memcpy(backup,dist,sizeof(backup));
    25         for(int j = 0; j < m;j++){
    26             int a = edges[j].a,b= edges[j].b,w = edges[j].w;
    27             dist[b] = min(dist[b],backup[a]+w);
    28         }
    29     }
    30     
    31     //更新过程中 无穷可能会减少或者一部分 所以未必就一定等于 0x3f3f3f3f
    32     if(dist[n] > 0x3f3f3f/2) return -1;
    33     
    34     return dist[n];
    35 }
    36 
    37 
    38 
    39 
    40 int main()
    41 {
    42     scanf("%d%d%d",&n,&m,&k);
    43     
    44     for(int i = 0; i < m;i++){
    45         int a,b,w;
    46         scanf("%d%d%d",&a,&b,&w);
    47         edges[i] = {a,b,w};
    48     }
    49     
    50     int t = bellman_ford();
    51     
    52     if(t == -1) printf("impossible");
    53     else printf("%d
    ",t);
    54     
    55     return 0;
    56 }
    acwing 853

    3 Floyd

    两点之间的最短路肯定是引进了第三方点的路线比现在的更短。

    所以 三个循环得到最短路径  次序不能颠倒 K是第三方点 只有尝试过其他 ij后,才能确定当前K点路径是最小值 才能进行以后点的遍历

     1 #include <iostream>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 
     7 const int N = 200;
     8 
     9 int n,m,q;
    10 int d[N][N];
    11 int INF = 1e9;
    12 
    13 
    14 void floyd(){
    15     for(int k = 1;k <=n;k++)
    16         for(int i = 1;i<=n;i++)
    17             for(int j = 1;j <= n;j++)
    18                 d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
    19                 
    20 }
    21 
    22 
    23 
    24 int main()
    25 {
    26    scanf("%d%d%d",&n,&m,&q);
    27    
    28    for(int i = 0; i <= n;i++){
    29         for(int j = 0; j <=n;j++){
    30             if(i == j) d[i][j] = 0;
    31             else d[i][j] = INF;
    32         }       
    33    }
    34     
    35     while(m--){
    36         int a,b,w;
    37         scanf("%d%d%d",&a,&b,&w);
    38         
    39         d[a][b] = min(d[a][b],w);
    40     }
    41         
    42     floyd();
    43     
    44     while(q--){
    45         int a,b;
    46         scanf("%d%d",&a,&b);
    47         if(d[a][b] > INF/2) printf("impossible
    ");
    48         else printf("%d
    ",d[a][b]);
    49         
    50     }
    51     
    52     return 0;
    53 }
    acwing 854

    4 spfa

     1 #include <iostream>
     2 #include <string>
     3 
     4 
     5 using namespace std;
     6 
     7 //更新过谁 再拿谁去更新别人
     8 
     9 #include <cstring>
    10 #include <iostream>
    11 #include <algorithm>
    12 #include <queue>
    13 
    14 using namespace std;
    15 
    16 const int N = 100010;
    17 
    18 int n, m;
    19 int h[N], w[N], e[N], ne[N], idx;
    20 int dist[N];
    21 bool st[N];
    22 
    23 void add(int a, int b, int c)
    24 {
    25     e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
    26 }
    27 
    28 int spfa()
    29 {
    30     memset(dist, 0x3f, sizeof dist);
    31     dist[1] = 0;
    32 
    33     queue<int> q;
    34     q.push(1);
    35     st[1] = true;
    36 
    37     while (q.size())
    38     {
    39         int t = q.front();
    40         q.pop();
    41 
    42         st[t] = false;
    43 
    44         for (int i = h[t]; i != -1; i = ne[i])
    45         {
    46             int j = e[i];
    47             if (dist[j] > dist[t] + w[i])
    48             {
    49                 dist[j] = dist[t] + w[i];
    50                 if (!st[j])
    51                 {
    52                     q.push(j);
    53                     st[j] = true;
    54                 }
    55             }
    56         }
    57     }
    58 
    59     return dist[n];
    60 }
    61 
    62 int main()
    63 {
    64     scanf("%d%d", &n, &m);
    65 
    66     memset(h, -1, sizeof h);
    67 
    68     while (m -- )
    69     {
    70         int a, b, c;
    71         scanf("%d%d%d", &a, &b, &c);
    72         add(a, b, c);
    73     }
    74 
    75     int t = spfa();
    76 
    77     if (t == 0x3f3f3f3f) puts("impossible");
    78     else printf("%d
    ", t);
    79 
    80     return 0;
    81 }
    acwing 851
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    数据库自动重连
    golang slice分割和append copy还是引用
    Unicode和UTF-8的关系
    golang的内置类型map的一些事
    svn sync主从同步学习
    CMake学习笔记
    常用排序总结
    优先队列实现Huffman编码
    linux 下C++查询mysql数据库
    ubuntu下C++连接mysql数据库
  • 原文地址:https://www.cnblogs.com/itdef/p/11474065.html
Copyright © 2011-2022 走看看