并查集入门:HDU1232畅通工程

题目描述

跟hd1272不同、这道题就对成环不敏感了,能走就行,只在乎祖宗数量,祖宗之间形成不成环的链接

直接上代码把

#include<iostream>
using namespace std;
typedef long long ll;
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void Out(ll a)
{
	if (a < 0)putchar('-'), a = -a;
	if (a >= 10)Out(a / 10);
	putchar(a % 10 + '0');
}

int f[1007];//按照数剧不大于1000开得全局数组
void intital_set(int x) {

	for (int i = 1; i <= x; i++)
		f[i] = i;//初始化数组
}
int getfather(int x) {
	if (f[x] != x) {
		f[x] = getfather(f[x]);
	}
	return f[x];//返回x的话相当于没压缩路径,达不到儿子直接连祖宗的效果,当然,也只是暂时的连着祖先,如果祖先后续当儿子,另说
}
void unionset(int x, int y) {
	f[x] = getfather(x);//找一下祖先,不写的话找的只是父亲不是祖先,最后变成比较父亲一不一样
	f[y] = getfather(y);//不能保证之前的祖先f【x】不变成别人的儿子。。。总感觉这段话怪怪的
	if (f[x] == f[y])//祖先一样那没事了,一个家族的
		return;
	f[f[x]] = f[y];//x家族做y家族儿子//操作对象应该是祖先,两边不加多套f操作的是孩子的f值,会导致儿子换祖先,而且换的y还不是y家族的祖先
}
int main() {

	int num_point;//点数
	int num_road;//路径数
	int x, y;
	int  time = 0;
	intital_set(1000);
	while (num_point = read()) {
		if (!num_point) {
			break;
		}
		num_road = read();
		for (int i = 1; i <= num_road; i++) {
			x = read();
			y = read();
			unionset(x, y);
		}
		for (int i = 1; i <= num_point; i++) {
			if (f[i] == i) {//是祖先
				time++;//祖先数量加1
			}
		}
		Out(--time);//祖先数量-1等于完全联通所需的路程,即把祖先之间在连起来就行了
		puts("");
		intital_set(num_point);//数组状态返回
		time = 0;//置0
	}



}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值