求助一道最小生成树站外题
  • 板块题目总版
  • 楼主渡鸦2007
  • 当前回复3
  • 已保存回复3
  • 发布时间2020/11/3 22:29
  • 上次更新2023/11/5 09:04:40
查看原帖
求助一道最小生成树站外题
385748
渡鸦2007楼主2020/11/3 22:29
题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;
}

2020/11/3 22:29
加载中...