这个程序从标准输入读取小于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;
}
p | q | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
3 | 4 | 0 | 1 | 2 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | |
4 | 9 | 0 | 1 | 2 | 9 | 9 | 5 | 6 | 7 | 8 | 9 | |
8 | 0 | 0 | 1 | 2 | 9 | 9 | 5 | 6 | 7 | 0 | 9 | |
2 | 3 | 0 | 1 | 9 | 9 | 9 | 5 | 6 | 7 | 0 | 9 | |
5 | 6 | 0 | 1 | 9 | 9 | 9 | 6 | 6 | 7 | 0 | 9 | |
2 | 9 | 0 | 1 | 9 | 9 | 9 | 6 | 6 | 7 | 0 | 9 | |
5 | 9 | 0 | 1 | 9 | 9 | 9 | 9 | 9 | 7 | 0 | 9 | |
7 | 3 | 0 | 1 | 9 | 9 | 9 | 9 | 9 | 9 | 0 | 9 | |
4 | 8 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
5 | 6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
0 | 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
6 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
可以用下面的代码替换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实现合并操作。