首页 > 代码库 > poj 3723 Conscription 【最大生成树|最大权森林】
poj 3723 Conscription 【最大生成树|最大权森林】
题目:poj 3723 Conscription
题意:要征兵n个男兵和m个女兵,每个花费10000元,但是如果已经征募的男士兵中有和将要征募的女士兵关系好的,那么可以减少花费,给出关系,求最小花费。
分析:这个题目初始一个是个二分图,以为可以从这里入手,但是这个题目这个性质没用。
初始花费没人10000,那么减去其中有关系的就是当前的花费。
要是花费最少,那么减去的最大即可,又因为没人只征募一次,即最多选择一个,所以减去一个最大生成树就ok
AC代码:
#include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; const int N = 52000; const int M = 55000; int u[N],v[N],w[N]; int cmp(int x,int y) { return w[x]>w[y]; } int father[N],p[N]; int find(int x) { if(father[x]==x) return x; return father[x] = find(father[x]); } int kru(int n, int m) { int ans=0, i; for(i=0; i<m; i++) p[i]=i; for(i=0; i<n; i++) father[i]=i; sort(p, p+m, cmp); for(i=0; i<m; i++) { int e=p[i]; int x=find(u[e]); int y=find(v[e]); if(x!=y) {ans+=w[e]; father[x]=y;} } return ans; } int main() { //freopen("a.txt","r",stdin); int n,m,r,T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&r); for(int i=0;i<r;i++) { int x; scanf("%d%d%d",&u[i],&x,&w[i]); v[i] = x+n; } int css = kru(m+n,r); printf("%d\n",(n+m)*10000-css); } return 0; }
poj 3723 Conscription 【最大生成树|最大权森林】
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。