题1 奴隶阿飞的励志人生
【问题描述】
阿飞建立了他的第二个城池——飞哥皇冠瑜伽会所。告别了斯昆五剑圣(国防外包生活)的阿飞,希望建立一支军队来保护他的城池。
阿飞选中了N个女孩和M个男孩,希望招募他们成为他的战士。一般来说,招募一个人需要花费10000开币。不过,老谋深算的阿飞发现,可以利用这些人之间的关系来减少他的花费——如果女孩X和男孩Y存在关系值D(两人之间可能有多个关系值),而且他们之中有一个人被招募了。那么阿飞就可以在招募另一个人的时候减少D的花费(实际花费10000-D开币)。
现在给你这些男孩女孩之间的关系,希望你告诉阿飞告诉他招募所有人的最少花费。
注意:招募某一个人时,只能利用一个关系。
【输入格式】
输入文件conscription.in中第一行包含三个整数N,M,R。表示N个女孩,M个男孩与R条关系。
接下来R行,每行包含三个整数Xi,Yi和Di,表示女孩Xi和男孩Yi有Di的关系。
【输出格式】
conscription.out中只有一行一个数为最小费用。
【输入输出样例】
conscription.in
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
conscription.out
71071
【数据规模】
100%的数据: 1 <= N, M <= 100000
0 <= R <= 200,000
0 < di < 10000
bdfs无果,按老师题解是最小生成树,但我的程序样例输出是61071
各位大佬如有时间能否帮忙看下,感激不尽
若有违反社区规则请原谅且我会尽快删除 如果机房有网
注意,输入中编号从0开始
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
//#include<string>
//#include<queue>
//#include<bits/stdc++.h>
using namespace std;
struct line
{
int x,y,d;
}l[200010];
int fa[200010];
bool px(line a,line b)
{
return a.d <b.d ?1:0;
}
int find(int a)
{
if (fa[a]!=a)
{
fa[a]=find(fa[a]);
return fa[a];
}
else
return a;
}
int main()
{
//freopen("conscription.in","r",stdin);
//freopen("conscription.out","w",stdout);
int n,m,r;
scanf("%d%d%d",&n,&m,&r);
for (int i=1;i<=r;++i)
{
scanf("%d%d%d",&l[i].x ,&l[i].y ,&l[i].d );
l[i].d =10000-l[i].d ;
l[i].y +=n;
}
for (int i=0;i<n+m;++i)
{
fa[i]=i;
}
int ans=0;
int t=0;
sort(l+1,l+r+1,px);
for (int i=1;i<=r;++i)
{
int fa1=find(l[i].x ),fa2=find(l[i].y );
if (fa1!=fa2)
{
ans+=l[i].d ;
fa[fa1]=fa2;
t++;
}
if (t==m+n-1)
break;
}
if (t<m+n-1)
ans+= (m+n-1-t)*10000;
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}