题目1012:畅通工程

题目描述:

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

解决:

  此题即为并查集的简单应用之一。直接贴代码,在关键之处都有详细注释

#include <iostream>
using namespace std;

int father[1001];//父节点的位置
int size[1001];//当前节点的深度

int Find(int nowloc)
{//查找根节点
	while(nowloc != father[nowloc])
	{
		father[nowloc] = father[father[nowloc]];
		nowloc = father[nowloc];
	}
	return nowloc;
}

bool Union(int first,int second)
{
	first = Find(first);
	second = Find(second);
	if (first == second)
	{//属于同一集合
		return 0;
	}
	else
	{//不属于同一集合
		//将小树合并到大树中
		if (size[first] < size[second])
		{
			father[first] = second;
			size[second] += size[first];
		}
		else
		{
			father[second] = first;
			size[first] += size[second];
		}
		return 1;
	}
}

int main()
{
	int N= 0,M = 0;
	cin >> N;
	while(0 != N)
	{
		cin >> M;
		int count = 0;//计算已经存在的最简单路径的条数
		//初始化
		for (int i = 0; i <= 1000; ++i)
		{
			father[i] = i;
			size[i] = 1;
		}

		for (int i = 1; i <= M; ++i)
		{
			int first,second;
			cin >> first >> second;
			if ( Union(first,second) == 1)
			{
			/*如果成功将first节点和second节点连接,因为初始化时认为这两个节点
			是不连通的,但是他们两个之间又确实存在一条通路,所以我们将简单通路的个数加1
			如果Union返回值为0,则说明first和second之间已经存在直接或者间接的简单路径
			所以不用加1,否则会导致重复计算
		    举例:集合某个时刻的状态如下(1,2,3)(4,5)(6)
			现在我们输入(5,6),则很明显,原先5和6之间不存在简单路径,现在就添加一条
			现在我们输入(1,2),则很明显,原先1和2之间已经存在简单路径了,再加1就是重复计算
			总而言之,对于每个集合内的元素,我们可以简单的认为其之间的路径可以简化为此种形式
			X-Y-Z-I-O-T
			故我们的count计算的就是其中连接符  -  的数量的多少。
			故最后需要新修建的路径条数为N - count - 1。可以自己动手画一画
			*/
				++count;
			}
		}
		
		cout << N - count - 1<< endl;

		cin >> N;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值