并查集学习

hdu1232问题:

首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性问题。比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支。如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了;如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了;如果是3个连通分支,则只要再修两条路……

输入:

第一行n,m。n表示城镇个数,m为道路数。

下面m行为各条道路与哪两个城镇相连。

4 2

1 3 

4 3

输出:

1

#include <bits/stdc++.h>
using namespace std;
int pre[1000];
int find(int x)
{
	int r = x;
	while (pre[r] != r)//寻根
		r = pre[r];
	int i = x, j;
	while (i != r)//压缩路径
	{
		j = pre[i];
		pre[i] = r;
		i = j;
	}
	return r;
}
//递归写法
int find_digui(int x)
{
	if (x = pre[x])return x;
	return pre[x] = find_digui(pre[x]);
}
void join(int x, int y)//给城镇修路,使两个连通分量相通
{
	int fx = find(x), fy = find(y);
	if(fx!=fy)
		pre[fx] = fy;
}
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++)
		pre[i] = i;
	while (m--)
	{
		int i, j;
		scanf("%d%d", &i, &j);
		join(i, j);
	}
	int root[1000];//用来标记是否是根节点
	memset(root, 0, sizeof(root));
	for (int i = 1; i <= n; i++)
		root[find(i)] = 1;
	int ans = 0;
	for (int i = 1; i <= n; i++)
		if (root[i])
			ans++;
	printf("%d\n", ans - 1);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值