首页 > 代码库 > 51nod1640(kruscal)

51nod1640(kruscal)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640

 

题意:中文题诶~

 

思路:kruscal

题目要求是在边权最大值最小的情况下总权值尽量大,注意其中的优先级;

可以先从小到大加边kruscal一遍得到最小的最大边权,再从大到小加边kruscal一遍即可得出答案;

注意第二边kruscal时要先判当前加的边权不大于限制边权再加边,不然构造的并查集是错的;

 

代码:

技术分享
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stdio.h>
 4 #define ll long long
 5 using namespace std;
 6 
 7 const int MAXN=2e5+10;
 8 const ll inf=0x7f7f7f7f7f;
 9 
10 struct node{
11     int x, y;
12     ll v;
13 }edge[MAXN];
14 
15 int pre[MAXN], n, m;
16 
17 bool cmp(node a, node b){
18     return a.v < b.v;
19 }
20 
21 int find(int x){
22     return pre[x]==x?x:pre[x]=find(pre[x]);
23 }
24 
25 ll jion(node edge, ll cnt){
26     if(edge.v>cnt) return 0;
27     int fx=find(edge.x);
28     int fy=find(edge.y);
29     if(fx==fy) return 0;
30     pre[fx]=fy;
31     return edge.v;
32 }
33 
34 void init(void){
35     for(int i=1; i<=n; i++){
36         pre[i]=i;
37     }
38 }
39 
40 void kruscal(void){
41     ll cnt=0, ans=0, cc=inf;
42     init();
43     sort(edge, edge+m, cmp);
44     for(int i=0; i<m; i++){
45         ll gg=jion(edge[i], cc);
46         cnt=max(cnt, gg);
47     }
48     init();
49     for(int i=m-1; i>=0; i--){
50         ans+=jion(edge[i], cnt);
51     }
52     printf("%lld\n", ans);
53 }
54 
55 int main(void){
56     scanf("%d%d", &n, &m);
57     for(int i=0; i<m; i++){
58         scanf("%d%d%lld", &edge[i].x, &edge[i].y, &edge[i].v);
59     }
60     kruscal();
61     return 0;
62 }
View Code

 

51nod1640(kruscal)