@xiaoziyao
        
        2020-10-19T10:17:07.000000Z
        字数 1086
        阅读 1508
    未分类
贪心+并查集妙题
考虑定义一条有向边的意义为把公主让给了,那么每个点一定入度为,所有的边会形成一个外向基环树森林。
贪心地把公主按照嫁妆从大到小排序,每个公主看成一条无向边,那么可行的方案一定会形成一个基环树森林。
用并查集维护所有王子组成的基环树,用标记来记录一个并查集代表的集合为基环树还是树,然后考虑选择一条边的方法:
#include<stdio.h>#include<algorithm>using namespace std;const int maxn=200005,maxm=200005;int n,m,e,ans;int f[maxn],flg[maxn];struct edge{int x,y,z;}g[maxm];inline int cmp(edge a,edge b){return a.z>b.z;}int find(int x){return f[x]==x? x:f[x]=find(f[x]);}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].z);sort(g+1,g+1+m,cmp);for(int i=1;i<=n;i++)f[i]=i;for(int i=1;i<=m;i++){int x=find(g[i].x),y=find(g[i].y);if(x==y){if(flg[x]==0)flg[x]=1,ans+=g[i].z;continue;}if(flg[x]+flg[y]<=1){f[y]=x,flg[x]=flg[x]+flg[y];ans+=g[i].z;}}printf("%d\n",ans);return 0;}
