Conscription POJ - 3723
阿新 • • 發佈:2017-08-12
sort ast most while other any follow sub 使用 and boy y have a relationship d and one of them has been collected, Windy can collect the other one with 10000-d RMB. Now given all the relationships between girls and boys, your assignment is to find the least amount of money Windy has to pay. Notice that only one relationship can be used when collecting one soldier.
Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to be his soldiers. To collect a soldier without any privilege, he must pay 10000 RMB. There are some relationships between girls and boys and Windy can use these relationships to reduce his cost. If girl x
Input
The first line of input is the number of test case.
The first line of each test case contains three integers, N, M and R.
Then R lines followed, each contains three integers xi, yi and di.
There is a blank line before each test case.
1 ≤ N, M ≤ 10000
0 ≤ R ≤ 50,000
0 ≤ xi < N
0 ≤ yi < M
0 < di < 10000
Output
For each test case output the answer in a single line.Sample Input
2 5 5 8 4 3 6831 1 3 4583 0 0 6592 0 1 3063 3 3 4975 1 3 2049 4 2 2104 2 2 781 5 5 10 2 4 9820 3 2 6236 3 1 8864 2 4 8326 2 0 5156 2 0 1463 4 1 2439 0 4 4373 3 4 8889 2 4 3133
Sample Output
71071 54223
題解:讓我們設想一下這樣的一個無向圖:在征募某個人a時,如果使用了a和b之間的關系,那麽就連一條a到b的邊。假設這個圖存在圈,那麽無論以什麽樣的順序征募這個圈上所有的人,都會產生矛盾
,因此可以知道這個圖是一片森林。反之,如果給了一片森林就可以使用對應的關系確定征募的順序。因此把人看作頂點,關系看作邊,那麽這個問題就可以轉化為求解無向圖中的最大權森林問題,也就
是把所有邊權取反之後用最小生成樹算法求解。
--------------------------------------摘自《挑戰程序設計競賽》
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 8 const int maxn=50005; 9 10 struct edge{ 11 int u,v,cost; 12 bool operator<(const edge& i)const{ 13 return cost<i.cost; 14 } 15 }; 16 17 edge es[maxn]; 18 int n,m,R,F[maxn]; 19 20 int Find(int a){ 21 if(a!=F[a]) F[a]=Find(F[a]); 22 return F[a]; 23 } 24 25 bool unite(int a,int b){ 26 int x=Find(a),y=Find(b); 27 if(x!=y) { F[x]=y; return true; } 28 else return false; 29 } 30 31 int Kruskal(){ 32 sort(es,es+R); 33 int ans=0; 34 for(int i=0;i<R;i++){ 35 edge e=es[i]; 36 if(unite(e.u,e.v)) ans=ans+e.cost; 37 } 38 return ans; 39 } 40 41 int main() 42 { int kase; 43 cin>>kase; 44 while(kase--){ 45 cin>>n>>m>>R; 46 int x,y,most; 47 for(int i=0;i<R;i++){ 48 scanf("%d%d%d",&x,&y,&most); 49 es[i]=(edge){x,y+n,-most}; 50 } 51 for(int i=0;i<n+m;i++) F[i]=i; 52 int ans=10000*(n+m)+Kruskal(); 53 cout<<ans<<endl; 54 } 55 return 0; 56 }
Conscription POJ - 3723