一个国王,他拥有一个国家。最近他因为国库里钱太多了,闲着蛋疼要征集一只部队要保卫国家。他选定了N个女兵和M个男兵,但事实上每征集一个兵他就要花10000RMB,即使国库里钱再多也伤不起啊。他发现,某男兵和某女兵之间有某种关系(往正常方面想,一共R种关系),这种关系可以使KING少花一些钱就可以征集到兵,不过国王也知道,在征兵的时候,每一个兵只能使用一种关系来少花钱。这时国王向你求助,问他最少要花多少的钱。
读入(conscription.in)
第一行:T,一共T组数据。
接下来T组数据,
第一行包括N,M,R
接下来的R行 包括Xi,Yi,Vi 表示如果招了第Xi个女兵,再招第Yi个男兵能省Vi元(同样表示如果招了第Yi个男兵,再招第Xi个女兵能也省Vi元)
输出(conscription.out)
共T行,表示每组数据的最终花费是多少(因为国库里的钱只有2^31-1,所以保证最终花费在maxlongint范围内)
样例输入
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
样例输出
71071
54223
数据范围
数据保证T<=5 ,m,n<=10000,r<=50000,Xi<=m,Yi<=n,Vi<=10000,结果<=2^31-1
题目选自http://hzwer.com/3559.html(一大神博客)
这道题是一个最大生成树,因为分成男女两个数组不好处理,我们就可以将女的编号+1,男的编号+N+1,放到一个数组里,这样就会好处理。剩下的就用Kruskal做了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct node{ 5 int male,money,female; 6 }; 7 node array[100005]; 8 int fa[100005]; 9 bool flag[100005]; 10 bool cmp(node x,node y) 11 { 12 return x.money>y.money; 13 } 14 int find(int x) 15 { 16 if(x==fa[x])return x; 17 else return fa[x]=find(fa[x]); 18 } 19 int main() 20 { 21 int T; freopen("conscription.in","r",stdin); 22 freopen("conscription.out","w",stdout); 23 scanf("%d",&T); 24 while(T--) 25 { 26 int n,m,r; 27 scanf("%d%d%d",&n,&m,&r); 28 for(int i=1;i<=r;i++) 29 { 30 scanf("%d%d%d",&array[i].female,&array[i].male,&array[i].money); 31 array[i].female++; 32 array[i].male=array[i].male+n+1; 33 } 34 sort(array+1,array+r+1,cmp); 35 for(int i=1;i<=m+n;i++) 36 fa[i]=i; 37 int l=0,ans=0,fe=0,ma=0; 38 for(int i=1;i<=r;i++) 39 { 40 int find1=find(fa[array[i].male]); 41 int find2=find(fa[array[i].female]); 42 if(find1!=find2) 43 { 44 if(!flag[fa[array[i].male]])ma++; 45 if(!fa[array[i].female])fe++; 46 fa[find1]=find2; 47 ans+=array[i].money; 48 flag[fa[array[i].male]]=true; 49 flag[fa[array[i].female]]=true; 50 } 51 } 52 printf("%d\n",10000*(m+n)-ans); 53 } 54 fclose(stdin); 55 fclose(stdout); 56 return 0; 57 }