51 Nod 1640 天气晴朗的魔法( Kruskall )

本文详细介绍了使用最小生成树算法解决特定问题的过程。通过两次遍历边集合,并采用不同的排序方式,确保找到满足条件的最小生成树。首先,对边按权值非递增排序并进行合并操作,得到一棵树;接着,对边按权值非递减排序,再次执行合并操作直至形成所需的最小生成树。
 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 using namespace std;
 4 const int maxn = 2e5+5;
 5 
 6 struct node{
 7     LL u,v,w;
 8     node(){}
 9     node(LL a,LL b,LL c):u(a),v(b),w(c){}
10 };
11 
12 LL f[maxn];
13 LL n,m;
14 vector<node>edge;
15 int Find(LL x)
16 {
17     if (f[x] != x)
18         f[x] = Find(f[x]);
19     return f[x];
20 }
21 
22 void Union(LL a, LL b)
23 {
24     int a1 = Find(a);
25     int b1 = Find(b);
26     if (a1 != b1)
27         f[a1] = b1;
28 }
29 bool cmp1(node a,node b)
30 {
31     return a.w>b.w;
32 }
33 bool cmp2(node a,node b)
34 {
35     return a.w<b.w;
36 }
37 int main()
38 {
39     ios::sync_with_stdio(false);
40     cin>>n>>m;
41     for(int i=1;i<=n;i++)
42         f[i]=i;
43     for(int i=0;i<m;i++){
44         LL a,b,c;
45         cin>>a>>b>>c;
46         edge.push_back(node(a,b,c));
47     }
48     sort(edge.begin(),edge.end(),cmp2);
49     LL k=0,max_num=-1;
50     for(int i=0;i<m;i++)
51     {
52         if(Find(edge[i].u)!=Find(edge[i].v))
53         {
54             Union(edge[i].u,edge[i].v);
55             max_num = max(max_num,edge[i].w);
56             k++;
57         }
58         if(k==(n-1))
59             break;
60     }
61     sort(edge.begin(),edge.end(),cmp1);
62     for(int i=1;i<=m;i++)
63         f[i]=i;
64     LL ans=0;
65     k=0;
66     for(int i=0;i<m;i++)
67     {
68         if(edge[i].w>max_num)continue;
69         if(Find(edge[i].u)!=Find(edge[i].v))
70         {
71             Union(edge[i].u,edge[i].v);
72             ans += edge[i].w;
73             k++;
74         }
75         if(k==(n-1))
76             break;
77     }
78     cout<<ans<<endl;
79     return 0;
80 }

 

转载于:https://www.cnblogs.com/ouyang_wsgwz/p/9580652.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值