题解 CF875F Royal Questions
开始想法是带权二分图匹配,一看n的范围2e5直接弃疗。然后就进行了一些思考。
我们先按照边权从大到小排序,因为不管怎么匹配你肯定先选最大的,很容易证明这个贪心会选最优值。
如果你每次加边会形成一个环(基环树),那就可以加上它的贡献。或者形成不超过一个环的连通图也是可以的。
看到网上这篇博文写的很好,这里引用一下:Orz
1 #include<stdio.h> 2 #include<algorithm> 3 #define it register int 4 #define il inline 5 using namespace std; 6 const int N=1000005; 7 int fa[N],n,m; 8 bool o[N]; 9 long long ans; 10 struct ky{ 11 int l,r,num; 12 bool operator<(const ky&p)const{ 13 return num>p.num; 14 } 15 }a[N]; 16 il int fd(it x){ 17 return fa[x]==x?x:fa[x]=fd(fa[x]); 18 } 19 il void mer(it u,it v,it x){ 20 it t1=fd(u),t2=fd(v); 21 if(o[t1]&&o[t2]) return ; 22 t1^t2?fa[t2]=t1,o[t1]|=o[t2]:o[t1]=1; 23 ans+=x; 24 } 25 il void fr(int &num){ 26 num=0;char c=getchar();int p=1; 27 while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar(); 28 while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 29 num*=p; 30 } 31 int main(){ 32 fr(n),fr(m); 33 for(it i=1;i<=m;++i) fr(a[i].l),fr(a[i].r),fr(a[i].num); 34 for(it i=1;i<=n;++i) fa[i]=i; 35 sort(a+1,a+1+m); 36 for(it i=1;i<=m;++i) mer(a[i].l,a[i].r,a[i].num); 37 printf("%lld",ans); 38 return 0; 39 }