原理
- 基于染色思想,一开始每个人都是自己的颜色
- 连接两个点时,把两个点设置成一个颜色
- 如果两个点颜色一样,说明是一伙的,否则不是
一、问题描述
所谓一个朋友圈子,不一定其中的人都相互认识。
例如:小明的朋友是小李,小李的朋友是小于,那么他们三个人属于一个朋友圈。
现在给出一些人的朋友关系,人按照从1到 n n n编号,在这中间会进行询问某两个人是否属于一个朋友圈,请你编写程序,实现这个过程。
输入格式
第一行两个整数, n n n, m m m, ( 1 (1 (1 ≤ \leq ≤ n n n ≤ \leq ≤ 10000 10000 10000 , 3 ≤ 3\leq 3≤ m m m ≤ \leq ≤ 100000 ) ) ),分别表示人物和操作数。
接下来有
m
m
m行,每行三个整数
a
,
b
,
c
,
(
a
⊂
[
1
,
2
]
,
1
≤
b
,
c
≤
n
)
a,b,c,(a\subset[1,2],1 \leq b,c \leq n)
a,b,c,(a⊂[1,2],1≤b,c≤n)
1.当
a
=
1
a=1
a=1时,代表新增一条已知信息,
b
,
c
b,c
b,c是朋友
2.当
a
=
2
a=2
a=2时,代表根据以上消息,询问
b
,
c
b,c
b,c是否是朋友
输出格式
对于每个 a = 2 a=2 a=2的操作,输出 [ Y e s ] [Yes] [Yes]或 [ N o ] [No] [No]代表询问的两个人是否是朋友关系。
- List item
输入样例
6 5
1 1 2
2 1 3
1 2 4
1 4 3
2 1 3
输出样例:
No
Yes
代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct UnionSet{
int *color;
int size;
}UnionSet;
UnionSet *initSet(int n){
UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
u->color = (int *)malloc(sizeof(int)*(n+1));
u->size = n+1;
int i;
for(i = 0; i < u->size; i++)
u->color [i] = i;
return u;
}
//判断颜色
int find(UnionSet *u,int idx){
return u->color[idx];
}
//合并
int merge(UnionSet *u,int a,int b){
if(find(u,a)==find(u,b))
return 0;
int acolor = find(u,a);
int i;
for(i=0;i<u->size;i++){
if(find(u,i)==acolor)
u->color[i] = u->color [b];
}
return 1;
}
void freeUnion(UnionSet *u){
if(!u)
return ;
free(u->color);
free(u);
}
int main(){
int n,m,i;
scanf("%d %d",&n,&m);
UnionSet *u = initSet(n);
for(i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
switch(a){
case 1:
merge(u,b,c);
break;
case 2:
printf("%s\n",find(u,b)==find(u,c)?"Yes":"No");
break;
}
}
return 0;
}