【问题描述】
某学校有N(<=20000)个学生,每个都有自己的宗教信仰,校长责成学生处主任调查,每个学生都不愿意说出自己信什么教,被逼急之后,才挤出一句:我与谁谁信同样的宗教。随着调查进行,校长需要主任随时回答她的提问。
【输入格式】
第一行一个整数N,表示有N个学生,编号为1..N。
接下一单词’begin’,表示调查或询问的开始,格式如下:
T x y:表示调查出学生x和学生y信同一种宗教;
Q x y:表示询问x,y是否信同一种宗教;
Q 0:表示询问当前调查出的有多少种不同的宗教;
调查或询问到遇到单词’end’结束。
【输出格式】
针对每个Q,如果是查询某两个同学是否信同一种宗教,则输出’Yes’或’No’。如果是查询当前调查出的不同宗教数,则输出这个数。
【输入样例】
6
Begin T 1 2
T 2 3
Q 1 3
Q 2 5
T 5 6
Q 0
T 4 5
Q 4 6
Q 3 4
Q 0
End.
【输出样例】
Yes
No
3
Yes
No
2
【数据范围】
N<=20000
简单的并查集运用,注意读入用%s,暂时没有提到的人算作信另一种宗教
#include<cstdio>
#include<cstring>
#define maxn 20005
using namespace std;
int n,x,y;
char s[15];
int fa[maxn];
bool vis[maxn];
void clear() //清空
{
for(int i=1;i<=n;i++) fa[i]=i;
}
int find(int x)
{
if(fa[x]==x) return x;
int t=find(fa[x]);
fa[x]=t;
return t;
}
void Union(int x,int y)
{
fa[find(x)]=find(y);
}
bool check(int x,int y)
{
return find(x)==find(y);
}
void task()
{
int ans=0;
for(int i=1;i<=n;i++) if(fa[i]==i) ans++;
printf("%d\n",ans);
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%d",&n);
clear();
while(1)
{
scanf("%s",s);
if(strcmp(s,"Begin")==0) continue;
if(strcmp(s,"End.")==0) break;
if(s[0]=='T')
{
scanf("%d%d",&x,&y);
//vis[x]=true,vis[y]=true;开始以为没提到的人不算,后来发现没有提到的人算作信另一宗教
Union(x,y);
}
if(s[0]=='Q')
{
scanf("%d",&x);
if(x==0) task();
else
{
scanf("%d",&y);
if(check(x,y)) printf("Yes\n");
else printf("No\n");
}
}
}
return 0;
}