码迷,mamicode.com
首页 > 其他好文 > 详细

最小生成树模板

时间:2020-01-17 11:52:50      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:main   pos   模板   print   flag   type   lld   name   优化   

最小生成树模板

prim

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e3+20;
 5 const int inf=0x3f3f3f3f;
 6 int G[maxn][maxn];
 7 bool vis[maxn];
 8 int dis[maxn];
 9 int sum,n,m;
10 
11 void prim(){
12     int pos=0;
13     sum=0;
14     memset(vis,false,sizeof(vis));
15     for(int i=1;i<=n;i++) dis[i] = G[1][i];
16     vis[1] = true;
17 
18     int flag=false,sum=0;
19     for(int i=1;i<n;i++){///n个顶点,(n-1)条边
20         int maxx = inf;
21         for(int j=1;j<=n; j++){
22             if( dis[j]<maxx && !vis[j] ){
23                 maxx = dis[j];
24                 pos = j;
25             }
26         }
27 
28         if( maxx==inf ){
29             flag = true;
30             break;
31         }
32 
33         sum += maxx;
34         vis[pos] = true;
35         for(int j=1;j<=n;j++){
36             if( !vis[j] && dis[j]>G[pos][j] ){
37                 dis[j] = G[pos][j];
38             }
39         }
40     }
41     if( flag==true ) printf("-1\n");
42     else printf("%d\n",sum);
43 }
44 
45 int main()
46 {
47     while( ~scanf("%d%d",&n,&m) ){
48         for(int i=1;i<=n;i++){
49             for(int j=1;j<=n;j++){
50                 if( i==j ) G[i][j] = 0;
51                 else G[i][j] = inf;
52             }
53         }
54 
55         while( m-- ){
56             int u,v,w;
57             scanf("%d%d%d",&u,&v,&w);
58             if( G[u][v]>w ){
59                 G[u][v] = w;
60                 G[v][u] = w;
61             }
62         }
63         prim();
64     }
65     return 0;
66 }

 

prim堆优化

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 2e5+10;
 5 const int maxx = 5e3+15;
 6 
 7 struct node{
 8     int to;
 9     int wi;
10     bool operator < (const node &a) const{
11         return wi>a.wi;
12     }
13 };
14 
15 int n,m;
16 int vis[maxx];
17 vector<node>e[maxx];
18 priority_queue<node>q;
19 
20 ll prim(){
21     ll ans=0;
22     int cnt=0;
23     q.push((node){1,0});
24     while( !q.empty() && cnt<=n ){
25         node k=q.top();
26         q.pop();
27         if( vis[k.to] ) continue;
28         vis[k.to] = 1;
29         ans += k.wi;
30         cnt++;
31         for(int i=0;i<e[k.to].size();i++){
32             if( !vis[e[k.to][i].to] ){
33                 q.push((node){e[k.to][i].to, e[k.to][i].wi});
34             }
35         }
36     }
37     return ans;
38 }
39 
40 int main()
41 {
42     scanf("%d%d",&n,&m);
43     for(int i=1; i<=m; i++){
44         int u,v,w;
45         scanf("%d%d%d",&u,&v,&w);
46         e[u].push_back((node){v,w});
47         e[v].push_back((node){u,w});
48     }
49     printf("%lld\n",prim());
50     return 0;
51 }

 

Kurscal

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 5010;
 5 const int maxx = 200100;
 6 const int inf=0x3f3f3f3f;
 7 const ll INF=0x3f3f3f3f3f3f3f3f;
 8 
 9 int fa[maxn];
10 int dis[maxn][maxn];
11 int n,m;
12 struct edge{
13     int ui;
14     int vi;
15     int wi;
16 }e[maxx];
17 
18 int find_fa(int u){
19     if( fa[u]==u ) return u;
20     return fa[u] = find_fa(fa[u]);
21 }
22 
23 void Merge(int u, int v){
24     int fu = find_fa(u);
25     int fv = find_fa(v);
26 
27     if( fu!=fv ){
28         fa[fv] = fa[fu];
29     }
30 }
31 
32 void init(){
33     for(int i=0;i<=n;i++){
34         fa[i] = i;
35     }
36 }
37 
38 bool cmp(edge a, edge b){
39     return a.wi<b.wi;
40 }
41 
42 int main()
43 {
44     scanf("%d%d",&n,&m);
45     for(int i=0;i<m;i++){
46         int u,v,w;
47         scanf("%d%d%d",&u,&v,&w);
48         e[i].ui = u;
49         e[i].vi = v;
50         e[i].wi = w;
51     }
52     sort(e,e+m,cmp);
53     init();
54     int top=0;
55     ll ans=0;
56     for(int i=0;i<m;i++){
57         int u = e[i].ui;
58         int v = e[i].vi;
59         int w = e[i].wi;
60         if( find_fa(u)!=find_fa(v) ){
61             Merge(u,v);
62             ans = ans + (ll)w;
63             top++;
64         }
65         if( top==n-1 ) break;
66     }
67 
68     if( top==n-1 ) printf("%lld\n",ans);
69     else printf("orz\n");
70     return 0;
71 }

最小生成树模板

标签:main   pos   模板   print   flag   type   lld   name   优化   

原文地址:https://www.cnblogs.com/wsy107316/p/12204828.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!