wenbao与最小生成树

Posted wenbao

tags:

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

 

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

 

Kruskal模板

 

 1 const int maxn = 105;
 2 int n, m, u[maxn], v[maxn], w[maxn], r[maxn], p[maxn];
 3 
 4 int cmp(const int i, const int j) { 
 5     return w[i] < w[j];
 6 }
 7 
 8 int findn(int x) {
 9     return p[x] == x ? x : p[x] = findn(p[x]);
10 }
11 
12 int Kruskal() {
13     int ans = 0, num = 0;
14     for(int i = 1; i <= m; ++i) p[i] = i;
15     sort(r, r+n, cmp);
16     for(int i = 0; i < n; i++) {
17         int e = r[i];
18         int x = findn(u[e]), y = findn(v[e]);
19         if(x != y) {
20             num ++;
21             ans += w[e];
22             p[x] = y;
23         }
24     }
25     if(num != m-1) printf("?\n");
26     else printf("%d\n", ans);
27 }

 

 

 

 离散课本实现

 

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 struct Node{
 5     int v, vv, w;
 6 }T[20];
 7 int cmp(Node a, Node b){
 8     return a.w < b.w;
 9 }
10 int TT[20];
11 int Find(int x){
12     return TT[x] == x ? x : TT[x] = Find(TT[x]);
13 }
14 void kru(int x){
15     for(int i = 0; i <= x; i++){
16         TT[i] = i;
17     }
18     int sum = 0;
19     sort(T, T+x, cmp);
20     for(int i = 0; i < x; i++){
21         int xx = Find(T[i].v);
22         int yy = Find(T[i].vv);
23         if(xx != yy){
24             sum += T[i].w;
25             TT[xx] = yy;
26         }
27     }
28     printf("%d\n", sum);
29 }
30 int main(){
31     int n;
32     scanf("%d", &n);
33     for(int i = 0; i < n; i++){
34         scanf("%d%d%d", &T[i].v, &T[i].vv, &T[i].w);
35     }
36     kru(n);
37 }

 

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

 prim

 

邻接表优化

 1 int head[111], Next[222], point[222], val[222], size, dist[111];
 2 int n, m, x, y, z;
 3 
 4 void add (int a, int b, int v) {
 5     int i;
 6     for(i = head[a]; ~i; i = Next[i]) {
 7         if(point[i] == b) {
 8             if(val[i] > v) val[i] = v;
 9             return;
10         }
11     }
12     point[size] = b;
13     val[size] = v;
14     Next[size] = head[a];
15     head[a] = size++;
16 }
17 
18 void prim() {   //prim函数,传入图中一点
19     memset(dist, 0x3f3f, sizeof(dist));
20     for(int i = head[1]; ~i; i = Next[i]){
21         dist[point[i]] = val[i];
22     }
23     dist[1] = -1;
24     int sum = 0;
25     for(int i = 2; i <= m; ++i){
26         int mi = 1e9, k = -1;
27         for(int j = 2; j <= m; ++j){
28             if(dist[j] != -1 && dist[j] < mi){
29                 mi = dist[j], k = j;
30             }
31         }
32         if(k == -1){
33             printf("?\n");
34             return ;
35         }
36         dist[k] = -1;
37         sum += mi;
38         for(int j = head[k]; ~j; j = Next[j]){
39             if(dist[point[j]] != -1 && dist[point[j]] > val[j]){
40                 dist[point[j]] = val[j];
41             }
42         }
43     }
44     printf("%d\n", sum);
45 }

 

 

邻接表优先队列优化

 1 typedef pair<int,int> pii;
 2 
 3 int head[30], next[200], point[200], val[200], size, dist[30];
 4 
 5 void add (int a, int b, int v) {   //加边及去重
 6     int i;
 7     for(i = head[a]; ~i; i = next[i]) {
 8         if(point[i] == b) {
 9             if(val[i] > v) val[i] = v;
10             return;
11         }
12     }
13     point[size] = b;
14     val[size] = v;
15     next[size] = head[a];
16     head[a] = size++;
17 }
18 
19 struct cmp {   //重载小根堆
20     bool operator()(pii a, pii b) {
21         return a.first > b.first;
22     }
23 };
24 
25 void prim(int s) {   //prim函数,传入图中一点
26     int i, ans = 0;
27     memset(dist, 0x3f, sizeof(dist));
28     priority_queue<pii, vector<pii>, cmp>q;
29     for (i = head[s]; ~i; i = next[i]) {
30         dist[point[i]] = val[i];
31         q.push(make_pair(dist[point[i]], point[i]));
32     }
33     dist[s] = -1;
34     while(!q.empty()) {
35         pii u = q.top();
36         q.pop();
37         if(dist[u.second] == -1) continue;
38         dist[u.second] = -1;
39         ans += u.first;
40         for(i = head[u.second]; ~i; i = next[i]) {
41             int j = point[i];
42             if(dist[j] > val[i]) {
43                 dist[j] = val[i];
44                 q.push(make_pair(dist[j], j));
45             }
46         }
47     }
48     printf("%d\n", ans);
49 }

 

 

 

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

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

 

prim

 

 1 #include "iostream"
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <queue>
 5 #include <stdio.h>
 6 using namespace std;
 7 typedef pair<int,int> pii;
 8 
 9 int head[111], Next[222], point[222], val[222], size, dist[111];
10 bool vis[111];
11 int n, m, x, y, z;
12 
13 void add (int a, int b, int v) {   //加边及去重
14     int i;
15     for(i = head[a]; ~i; i = Next[i]) {
16         if(point[i] == b) {
17             if(val[i] > v) val[i] = v;
18             return;
19         }
20     }
21     point[size] = b;
22     val[size] = v;
23     Next[size] = head[a];
24     head[a] = size++;
25 }
26 
27 struct cmp {   //重载小根堆
28     bool operator()(pii a, pii b) {
29         return a.first > b.first;
30     }
31 };
32 
33 void prim(int s) {   //prim函数,传入图中一点
34     int i, ans = 0, num = 0;
35     memset(dist, -1, sizeof(dist));
36     memset(vis, 0, sizeof(vis));
37     priority_queue<pii, vector<pii>, cmp>q;
38     for (i = head[s]; ~i; i = Next[i]) {
39         dist[point[i]] = val[i];
40         q.push(make_pair(dist[point[i]], point[i]));
41     }
42     dist[s] = 0;
43     vis[s] = 1;
44     while(!q.empty()) {
45         pii u = q.top();
46         q.pop();
47         if(vis[u.second]) continue;
48         vis[u.second] = 1;
49         ans += u.first;
50         num++;
51         for(i = head[u.second]; ~i; i = Next[i]) {
52             int j = point[i];
53             if(!vis[j] && (dist[j] > val[i] || dist[j] == -1)) {
54                 dist[j] = val[i];
55                 q.push(make_pair(dist[j], j));
56             }
57         }
58     }
59     if(num != m-1) printf("?\n");
60     else printf("%d\n", ans);
61 }
62 
63 int main(){
64 #ifdef wenbao
65     freopen("in", "r", stdin);
66 #endif
67     while(~scanf("%d%d", &n, &m)){
68         if(n == 0) break;
69         size = 0;
70         memset(head, -1, sizeof(head));
71         for(int i = 0; i < n; ++i){
72             scanf("%d%d%d", &x, &y, &z);
73             add(x, y, z), add(y, x, z);
74         }
75         prim(1);
76     }
77     return 0;
78 }

 

Kruskal

 

 1 #include "iostream"
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int maxn = 105;
 6 int n, m, u[maxn], v[maxn], w[maxn], r[maxn], p[maxn];
 7 
 8 int cmp(const int i, const int j) { 
 9     return w[i] < w[j];
10 }
11 
12 int findn(int x) {
13     return p[x] == x ? x : p[x] = findn(p[x]);
14 }
15 
16 int Kruskal() {
17     int ans = 0, num = 0;
18     for(int i = 1; i <= m; ++i) p[i] = i;
19     sort(r, r+n, cmp);
20     for(int i = 0; i < n; i++) {
21         int e = r[i];
22         int x = findn(u[e]);
23         int y = findn(v[e]);
24         if(x != y) {
25             num ++;
26             ans += w[e];
27             p[x] = y;
28         }
29     }
30     if(num != m-1) printf("?\n");
31     else printf("%d\n", ans);
32 }
33 
34 int main() {
35 #ifdef wenbao
36     freopen("in", "r", stdin);
37 #endif
38     while(~scanf("%d%d", &n, &m)){
39         if(n == 0) break;
40         for(int i = 0; i < n; ++i){
41             scanf("%d%d%d", &u[i], &v[i], &w[i]), r[i] = i;
42         }
43         Kruskal();
44     }
45     return 0;
46 }

 

 

 

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

 

 

 

 

 

只有不断学习才能进步!

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

wenbao与线段树

wenbao与RMP(线段树)

数据结构 图连通与最小生成树

图论算法零基础最小生成树学习与总结

最小生成树

图解:如何实现最小生成树(Prim算法与Kruskal算法)