wenbao与最短路dij

Posted wenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wenbao与最短路dij相关的知识,希望对你有一定的参考价值。



-----------------------

http://acm.hdu.edu.cn/showproblem.php?pid=1874

裸题

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 #define N 10000000
 7 int road[200][200], vis[200];
 8 int dij[200], n, m, start, l;
 9 
10 void Dij(){
11     int i, j, k, v, path;
12     memset(vis, 0, sizeof(vis));
13     for(i = 0; i < n; i++) dij[i]=road[start][i];
14     dij[start] = 0;
15     vis[start] = 1;
16     for(i = 0; i < n; i++){
17         path = N;
18         for(j = 0; j < n; j++){
19             if(!vis[j] && path > dij[j]){
20                 path = dij[j];
21                 v = j;
22             }
23         }
24         vis[v] = 1;
25         for(k = 0; k < n; k++){
26             if(!vis[k]) dij[k] = min(dij[k], dij[v]+road[v][k]);
27         }
28     }
29 }
30 
31 int main(){
32     int i, j, a, b, c;
33     while(scanf("%d%d", &n, &m) != EOF){
34         for(i = 0; i < n; i++){
35             for(j = 0; j < n; j++){
36                 if(i==j) road[i][j] = road[j][i] = 0;
37                 else road[i][j] = road[j][i] = N;
38             }
39         }
40         for(i = 0; i < m; i++){
41             scanf("%d%d%d", &a, &b, &c);
42             road[a][b] = road[b][a] = min(road[a][b], c);
43         }
44         scanf("%d%d", &start, &l);
45         Dij();
46         if(dij[l] < N) printf("%d\n", dij[l]);
47         else printf("-1\n");
48     }
49     return 0;
50 }

 

 

优先队列优化

 

 1 #include <iostream>
 2 #include <string.h>
 3 #include <queue>
 4 #include <vector>
 5 using namespace std;
 6 
 7 const int INF = 1e9;
 8 const int maxn = 209;
 9 const int maxr = 2009;
10 bool vis[maxn];
11 int dis[maxn], to[maxr], w[maxr], p[maxn], pre[maxr], index;
12 
13 struct Node{
14     int x, y;
15     bool friend operator < (Node a, Node b){
16         if(a.y == b.y) return a.x < b.x;
17         return a.y > b.y;
18     }
19 };
20 
21 void init(int x){
22     index = 1;
23     for(int i = 0; i <= x; ++i){
24         vis[i] = false, dis[i] = INF;
25         p[i] = 0;
26     }
27 }
28 
29 void Dij(int sta, int end){
30     priority_queue<Node> pq;
31     Node a, b;
32     a.x = sta, a.y = 0;
33     dis[sta] = 0;
34     pq.push(a);
35     while(!pq.empty()){
36         b = pq.top(); pq.pop();
37         int xx = b.x;
38         if(vis[xx]) continue;
39         vis[xx] = true;
40         for(int i = p[xx]; i; i = pre[i]){
41             int xxx = to[i];
42             if(!vis[xxx] && dis[xxx] > dis[xx] + w[i]){
43                 dis[xxx] = dis[xx] + w[i];
44                 a.x = xxx, a.y = dis[xxx];
45                 pq.push(a);
46             }
47         }
48     }
49     printf("%d\n", dis[end] == INF ? -1 : dis[end]);
50 }
51 
52 int main(){
53     int n, m, s, t, x, y, z;
54     while(~scanf("%d%d", &n, &m)){
55         init(n);
56         while(m--){
57             scanf("%d%d%d", &x, &y, &z);
58             to[index] = y, w[index] = z, pre[index] = p[x], p[x] = index++;
59             to[index] = x, w[index] = z, pre[index] = p[y], p[y] = index++;
60         }
61         scanf("%d%d", &s, &t);
62         Dij(s, t);
63     }
64     return 0;
65 }

 


---------------------------

升级版

http://acm.hdu.edu.cn/showproblem.php?pid=3790


 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 using namespace std;
 5 
 6 #define INF 0xfffffff
 7 #define maxn 1000
 8 
 9 int road[1000][1000], dij[maxn], money[1000][1000], dijm[maxn];
10 bool flag[maxn];
11 
12 void Dij(int start, int endn, int n){
13     memset(flag, 0, sizeof(flag));
14     int path, v;
15     for(int i = 1; i <= n; i++){
16         dij[i] = road[start][i];
17         dijm[i] = money[start][i];
18     }
19     flag[start] = 1;
20     dij[start] = 0;
21     for(int i = 1; i <= n; i++){
22         path = INF;
23         for(int j = 1; j <= n; j++){
24             if(!flag[j] && path > dij[j]){
25                 path = dij[j];
26                 v = j;
27             }
28         }
29         flag[v] = 1;
30         for(int k = 1; k <= n; k++){
31             if(!flag[k]){
32                 if(dij[k] == dij[v] + road[v][k]){
33                     if(dijm[k] > dijm[v] + money[v][k]){
34                         dij[k] = dij[v] + road[v][k];
35                         dijm[k] = dijm[v] + money[v][k];
36                     }
37                 }
38                 else if(dij[k] > dij[v] + road[v][k]){
39                     dij[k] = dij[v] + road[v][k];
40                     dijm[k] = dijm[v] + money[v][k];
41                 }
42             }
43         }
44     }
45 }
46 
47 int main(){
48     int a, b, c, d, start, endn, n, m;
49     while(scanf("%d%d", &n, &m), n+m){
50         for(int i = 1; i <= n; i++){
51             for( int j = 1; j < i; j++){
52                 road[i][j]=road[j][i]= money[i][j]=money[j][i]=INF;
53             }
54         }
55         for(int i = 0; i < m ; i++){
56             scanf("%d%d%d%d", &a, &b, &c, &d);
57             if(road[a][b] > c){
58                 road[a][b] = road[b][a] = c;
59                 money[a][b] = money[b][a] = d;
60             }
61         }
62         scanf("%d%d", &start, &endn);
63         Dij(start, endn, n);
64         printf("%d %d\n",dij[endn], dijm[endn]);
65     }
66     return 0;
67 }

 

 

-----------------------------

 

 邻接表加队列优化

 

 1 const int maxn = 1e5+10;
 2 bool vis[maxn];
 3 int dis[maxn];
 4 vector<int> vv[maxn];
 5 vector<int> v[maxn];
 6 
 7 struct Node{
 8     int x, y;
 9     bool friend operator < (Node a, Node b){
10         if(a.y == b.y) return a.x < b.x;
11         return a.y < b.y; //从大到小
12     }
13 };
14 
15 void Dij(int sta, int end){
16     memset(vis, false, sizeof(vis));
17     memset(dis, -1, sizeof(dis));//memset(dis, 0x3f, sizeof(dis));
18     priority_queue<Node> pq;
19     Node a, b;
20     a.x = sta, a.y = 0;//a,y = 0x3f;
21     dis[sta] = 0; // dis[sta] = 0x3f3f3f3f;
22     pq.push(a);
23     while(!pq.empty()){
24         b = pq.top(); pq.pop();
25         int xx = b.x;
26         if(vis[xx]) continue;
27         vis[xx] = true;
28         for(int i = 0; i < v[xx].size(); i++){
29             int xxx = v[xx][i];
30             if(!vis[xxx] && dis[xxx] > dis[xx] + vv[xx][i]){
31                 dis[xxx] = dis[xx] + vv[xx][i];
32                 a.x = xxx, a.y = dis[xxx];
33                 pq.push(a);
34             }
35         }
36     }
37     printf("%d\n", dis[end]);
38 }

 

 

 

 

离散课本实现

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 0x3f3f3f3f;
 4 int a[20][20], dis[20], n, m, b[20];
 5 bool vis[20];
 6 void dij(){
 7     for(int i = 2; i <= n; i++){
 8         dis[i] = maxn, b[i] = i;
 9     }
10     vis[1] = true, dis[1] = 0, b[1] = 1;
11     int x = 1;
12     for(int j = 0; j < n; j++){
13         for(int i = 1; i <= n; i++){
14             if(!vis[i] && dis[x] + a[x][i] < dis[i]){
15                 dis[i] = dis[x] + a[x][i], b[i] = x;
16             }
17         }
18         int mi = maxn+1;
19         for(int k = 1; k <= n; k++){
20             if(!vis[k] && dis[k] < mi){
21                 mi = dis[k], x = k;
22             }
23         }
24         vis[x] = true;
25     }
26 }
27 int main(){
28     scanf("%d%d", &n, &m);
29     for(int i = 1; i <= n; i++){
30         for(int j = 1; j <= n; j++){
31             a[i][j] = maxn;
32         }
33     }
34     for(int i = 0; i < m; i++){
35         int x, y, z;
36         scanf("%d%d%d", &x, &y, &z);
37         a[x][y] = a[y][x] = z;
38     }
39     dij();
40     for(int i = 1; i <= n; i++){
41         printf("%d**********%d\n", dis[i], b[i]);
42     }
43     return 0;
44 }

 

 

 

只有不断学习才能进步!

 

以上是关于wenbao与最短路dij的主要内容,如果未能解决你的问题,请参考以下文章

wenbao与最短路(spfa)

wenbao与最短路floyd

wenbao与最短路(dfs)

wenbao与多源多汇最短路

wenbao与最优比率生成树

wenbao与次短路