题意:招募n个女生与m个男生,每人花费需10000,若两人间存在亲密度,则可少花费两人的亲密度,求最小花费;
思路:相当于一幅无向图,给定边权,求权值和最大的森林,结果为10000*(n+m)-权值和;
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; struct edge{ int u,v,w; }ee[50010]; int fa[50010]; int n,m,r,res; int cmp(edge a,edge b){ return a.w>b.w; } void init(){ for(int i=0;i<50010;i++){ fa[i]=-1; } } int find(int x){ if(fa[x]==-1) return x; return fa[x]=find(fa[x]); } int combine(int a,int b){ int t1=find(a); int t2=find(b); if(t1==t2) return 0; fa[t1]=t2; return 1; } void kruskal(){ sort(ee,ee+r,cmp); for(int i=0;i<r;i++){ if(combine(ee[i].u,n+ee[i].v)) res+=ee[i].w; } } int main(){ int i,j,k,u,v,w,t; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&r); memset(ee,0,sizeof(ee)); init(); res=0; for(i=0;i<r;i++){ scanf("%d%d%d",&u,&v,&w); ee[i].u=u;ee[i].v=v;ee[i].w=w; } kruskal(); printf("%d\n",10000*(n+m)-res); } return 0; }
时间: 2024-10-17 04:36:37