题目链接: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 ", 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 }