这道题和并查集类似,这里我理解为第一个人的辈分小于第二个人,最后是亲戚的就会指向辈分最大的人,用递归来转辈分,用数组来存辈分。
代码如下:
#include<stdio.h>
int a[10000];
int ld(int k)
{
if(a[k]==k) return k;
return a[k]=ld(a[k]);
}
int main()
{
int q,w,e;
scanf("%d%d%d",&q,&w,&e);
for(int i=1;i<=q;i++)
a[i]=i;
for(int i=0;i<w;i++){
int n,m;
scanf("%d%d",&n,&m);
a[ld(n)]=ld(m);
}
for(int i=0;i<e;i++){
int t,y;
scanf("%d%d",&t,&y);
if(ld(t)==ld(y))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
进阶版:
思路:和刚才那个题一样将朋友用数组存起,是朋友的都指向最初的朋友;
然后判断和第一个朋友的朋友有多少个,最后输出小的那个+1(小明和小红也是一对);
注意:这里有两个公司所以要用两个数组,而且有个公司用负数表示,所以这里要再加一个负号变为正数。
代码如下:
#include<stdio.h>
int a[100000],b[100000];
int py(int k,int m[])
{
if(m[k]==k) return k;
return m[k]=py(m[k],m);
}
int main()
{
int q,w,e,r;
scanf("%d%d%d%d",&q,&w,&e,&r);
for(int i=1;i<=q;i++)
a[i]=i;
for(int i=1;i<=w;i++)
b[i]=i;
for(int i=0;i<e;i++){
int n,m;
scanf("%d%d",&n,&m);
a[py(n,a)]=py(m,a);
}
for(int i=0;i<r;i++){
int t,y;
scanf("%d%d",&t,&y);
b[py(-t,b)]=py(-y,b);
}
int man=0,woman=0;
for(int i=2;i<=q;i++){
if(a[py(1,a)]==py(i,a))
man++;
}
for(int i=2;i<=w;i++){
if(b[py(1,b)]==py(i,b))
woman++;
}
if(man<woman)
woman=man;
printf("%d",woman+1);
return 0;
}