并查集--杭电1232--畅通工程

杭电畅通工程问题要求计算使所有城镇互通所需的最少道路数量。通过并查集算法,可以高效地找出连通分量的数量。关键在于正确设置每个节点的父节点,确保不覆盖之前的连接。输入包含城市和已有的道路数量,输出应为所需额外道路的最小数量。示例展示了如何应用并查集找到正确的前导点序列。
摘要由CSDN通过智能技术生成

杭电畅通工程


问题描述:n个城镇,任何两个城镇可以互通,还需要多少条路?
思路:就是查找连通分量的个数,标记每一个结点的前导点,判断是否根节点是否一致。有x个连通分量,那么就需要至少x-1条边 
输入:n个城市 m条边 

通过并查集的思想可以很有效的求出连通分量的个数。以下有一个点非常重要,p1 = find(a);p2 = find(b);如果二者的root不同,那么现在给定的a-b的连线,就需要将这俩的root标记成相同的。如果每一次都用p(a) = p(b),

测试一下:可以发现,每一次的前导点会覆盖掉之前的,形不成并查集。

3 3
2 1
2 3
3 1
1  3  1

正确写法是:par[p1] = p2;

/*
杭电畅通工程
问题描述:n个城镇,任何两个城镇可以互通,还需要多少条路?
思路:就是查找连通分量的个数,标记每一个结点的前导点,判断是否根节点是否一致。有x个连通分量,那么就需要至少x-1条边 
输入:n个城市 m条边 
*/
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;

const int MAX_N = 1000;
int par[MAX_N];

int find(int root){
	int son = root;
	while(par[root] != root){
		root = par[root];
	}
	while(son!=root){
		int tmp = par[son];
		par[son] = root;
		son = tmp;
	}
	return root;	
}
int main(){
	int n, m,a,b;	// n个城市,m条路 ,a---b
	set<int> s;
	while(cin>>n && n){
		int total = n - 1;
		for(int i = 1; i <= n; i++) par[i] = i;	// 全部初始化为自己 
		cin>>m;
		while(m--){
			cin>>a>>b;
			int p1,p2;
			p1 = find(a);
			p2 = find(b);
			if (p1 != p2){	// 说明还没有联通 
				par[p1] = p2;
				total -= 1;
			}
		}
		for(int i = 1; i <= n; i++) cout<<par[i]<<"  ";
		cout<<endl<<"还需要"<<total<<endl;
	}
	return 0;
}

输入: 

10 9
7 8
9 1
8 1
6 2
3 2
5 10
10 4
4 5
3 6
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0

第一个例子的输出前导点序列:1  2  2  4  4  2  8  1  1  4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值