P2330 [SCOI2005] 繁忙的都市(二分+并查集)

直接替代码及注释吧

#include<iostream>
#include<algorithm>
using namespace std;
struct side
{
	int spot1, spot2, value;//起始点,边的价值
};
int n, m,f[10010];
bool cmp(side a, side b)//定义一个sort排序
{
	if (a.value <= b.value)
		return true;
	else
		return false;
}
int find(int x)//并查集模板,查找父节点
{
	if (x == f[x]) return x;
	f[x] = find(f[x]);
	return f[x];
}
side fa[10010];
bool check(int k)//判断当前二分的道路的分值是否能满足将所有路口遍历完
{
	for (int i = 1; i <= n; i++)
		f[i] = i;				//初始化并查集
	for (int i = 1; i <= m; i++)
	{
		if (fa[i].value > k)//如果分值已经大于二分的值了,后面就不能要了
			break;
		if (find(fa[i].spot1) != find(fa[i].spot2))//如果他们的父节点不是一个(即他们没有连通)
			f[find(fa[i].spot1)] = find(fa[i].spot2);//就将他们的父节点连通
	}
	int fin = 0;
	for (int i = 1; i <= n; i++)//循环遍历判断这些道路能不能连通全部路口
	{
		if (f[i] == i)//如果这一个节点没有被改变(即f[i]==i),fin++
			fin++;
	}
	if (fin == 1)//有且仅有一个节点没有被改变,说明所有道路已经联通了
		return true;
	return false;
}
int main()
{
	
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
		cin >> fa[i].spot1 >> fa[i].spot2 >> fa[i].value;
	sort(fa + 1, fa + m + 1, cmp);
	int l = fa[1].value, r = fa[m].value;//二分的区间
	while (l < r)//二分查找最小的那个分值
	{
		int mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	int ans = l;
	int res;
	//这里可以数学推断出res=n-1
	cout << n-1<< ' ' << ans;


	return 0;
}

这一题主要是用二分找到最大的最小分值,然后是用并查集判断是否连通

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值