并查集训练题 宗教信仰

【问题描述】

  某学校有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值