图论 最短路专辑

时间:2019-09-06
本文章向大家介绍图论 最短路专辑,主要包括图论 最短路专辑使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

先上总结构图

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\n", 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\n",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\n");
48         else printf("%d\n",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\n", t);
79 
80     return 0;
81 }
acwing 851

原文地址:https://www.cnblogs.com/itdef/p/11474065.html