先上總結構圖ios
1 首先來看Dijkstraide
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 }
2 bellman_fordspa
優點在於 能夠求出使用K次邊的狀況下的最短路徑 code
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 }
3 Floydblog
兩點之間的最短路確定是引進了第三方點的路線比如今的更短。ci
因此 三個循環獲得最短路徑 次序不能顛倒 K是第三方點 只有嘗試過其餘 ij後,才能肯定當前K點路徑是最小值 才能進行之後點的遍歷string
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 }
4 spfait
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 }