poj 3723 Conscription 【最大生成樹|最大權森林】
阿新 • • 發佈:2019-01-29
題意:要徵兵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; }