连通问题-快速查找算法

这个程序从标准输入读取小于N的非负整数对序列(对p-q表示“把对象p连接到q”),并且输出还未连通的输入对。程序中使用数组id,每个元素表示一个对象,且具有以下性质,当且仅当p和q是连通的,id[p]和id[q]相等。为简化起见,定义N为编译时的常数。

1.1

#include<stdio.h>
#define N 10000
int main()
{
	int i,p,q,t,id[N];
	for(i=0;i<N;i++)
		id[i]=i;
	while(scanf("%d%d\n",&p,&q) == 2)   //scanf的返回值是正确输入的个数
	{
		if(id[p]==id[q])
			continue;    //如果id[p]==id[q],那么不会进行这一次循环
		for(t=id[p],i=0;i<N;i++)
		{
			if(id[i]==t)
				id[i]=id[q];   //将id[q]的值给id[i](值等于id[p]的)
		}
		printf(" %d %d\n",p,q);
	}
	return 0;
}
pq0123456789
 340124456789
490129956789
800129956709
230199956709
560199966709
290199966709
590199999709
730199999909
480100000000
560100000000
020100000000
611111111111

可以用下面的代码替换1.1中的while循环体

1.2

    for(i=p; i!=if[i]; i=id[i]);
    for(j=q; j!=id[j]; j=id[j]);
    if(i==j) continue;
    id[i]=j;
    printf(" %d %d\n",p,q);

这个代码中的for循环以及其后的if语句指明了在数组id中p和q是连通的充要条件。赋值语句id[i] = j实现合并操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值