hdu 1232 畅通工程

畅通工程
思路
城市之间由道路连接,相连的城市可以看做一个集合,如:a、b相连,c、d相连,则a和b属于集合A,c和d属于集合B。之后又有人告诉你b和e相连,那么就把e加入到集合A中,以此类推。然后不同集合若是想组成一个大的集合,即集合A和集合B若相连接在一起,那随便在两个集合中分别找两个城市连接在一起就可以了。
考点
并查集

#include<stdio.h>
int fa[1010];
int find(int i){//寻找 根(父节点) 
	if(fa[i]!=i){//领导人的集合就是自己 
		fa[i]=find(fa[i]);//递归实现找到最终的领导人
	} 
	return fa[i];
}
void merge(int x,int y){//合并,使其各根(父节点)归属为一个最终根上 
	int tx,ty;
	tx=find(x);
	ty=find(y);
	if(tx!=ty){
		fa[ty]=tx;//将两领导人归属到其中一个最终大boos上  
	}
}
int main()
{
	int n,m,x,y;
	while(scanf("%d",&n)==1){
		if(n==0) break;
		for(int i=1;i<=n;++i){//注意:开始必须初始化所有的节点的前导都是自己,
			fa[i]=i;
		}
		scanf("%d",&m);
		for(int j=0;j<m;++j){
			scanf("%d%d",&x,&y);
			merge(x,y);
		}
		fa[0]=-1;//两个城镇一条路 
		for(int i=1;i<=n;i++){
			if(fa[i]==i)//大boos就是本身,所以找有多少本身,就有几个大booss(不相干集合) 
				fa[0]++;
		}
		printf("%d\n", fa[0]); 
	}
	return 0;
} 

老师视角
*分析
1.连通的城镇在一个集合中,不连通的城镇分布在互不相交的集合中,集合是树形结构
2.初始时,各个城镇互不连通,即有N个集合(N个互不相交的集合)
3.在查询过程中,查询路径上的城镇成为根的儿子,称为:路径压缩。

#include<bits/stdc++.h>
using namespace std;
#define MXN 1010
int N, M, fa[MXN];
int find(int r){
	if(r != fa[r]) fa[r] = find(fa[r]); // 路径压缩
	return fa[r];
}
void merge(int a, int b){
	int t1 = find(a);
	int t2 = find(b);
	if(t1 != t2) fa[t1] = t2;
}
int main(){
	int x, y;
	while(scanf("%d", &N) == 1){
		if(N == 0) break;
		scanf("%d", &M);
		for(int i = 1; i <= N; i++) fa[i] = i;		
		for(int i = 1; i <= M; i++){
			scanf("%d %d", &x, &y);
			merge(x, y);
		}
		fa[0] = -1;
		for(int i = 1; i <= N; i++) if(fa[i] == i) fa[0]++;
		printf("%d\n", fa[0]);
	}
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值