第十四届华中科技大学程序设计竞赛C Professional Manager

链接: https://www.nowcoder.com/acm/contest/106/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

It’s universally acknowledged that there’re innumerable trees in the campus of HUST. 

Thus a professional tree manager is needed. Your task is to write a program to help manage the trees. 
Initially, there are n forests and for the i-th forest there is only the i-th tree in it. Given four kinds of operations.

1 u v, merge the forest containing the u-th tree and the forest containing the v-th tree;

2 u, separate the u-th tree from its forest;

3 u, query the size of the forest which contains the u-th tree;
4 u v, query whether the u-th tree and the v-th tree are in the same forest.

输入描述:

 
 

The first line contains an integer T, indicating the number of testcases.

In each test case:

The first line contains two integers N and Q, indicating the number of initial forests and the number of operations.

Then Q lines follow, and each line describes an operation.

输出描述:

For each test cases, the first line should be "Case #i:", where i indicate the test case i.
For each query 3, print a integer in a single line.
For each query 4, print "YES" or "NO" in a single line.

题意:

最初,这里有n个森林,第i个森林里只有i-th树。有四种操作。

1 u v,将包含u-th树的森林和含有v-th树的森林合并在一起;
u,将u-th树与森林分开;
3 u,查询包含u-th树的森林的大小;

4 u v,查询u-th树和v-th树是否在同一林中。

思路:并查集;

AC代码:

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
 
int T,n,m,num,id[200005],siz[200005],fa[200005];///id编号 siz森林大小 fa并查集
int x,y,ty;
 
int getfa(int x)///路径压缩
{
    if (fa[x]!=x) fa[x]=getfa(fa[x]);
    return fa[x];
}
int main()
{
    scanf("%d",&T);
    for (int z=1;z<=T;++z)
    {
        printf("Case #%d:\n",z);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i) id[i]=i, fa[i]=i,siz[i]=1;///初始化
        num=n;
      
        while (m--)
        {
            scanf("%d",&ty);
            if (ty==1)///合并x--> y
            {
                scanf("%d%d",&x,&y);
                x=id[x];y=id[y];
                x=getfa(x);y=getfa(y);
                if (x==y) continue;
                fa[x]=y;///合并x--> y
                siz[y]+=siz[x];///y森林有几棵树
            }
            else
            if (ty==2)///分离
            {
                scanf("%d",&x);
                y=id[x];y=getfa(y);
                siz[y]--;///x所属森林减去1棵树
                ++num;id[x]=num;///将X编号改为新的++num
                fa[num]=num;siz[num]=1;
                
            }
            else
            if (ty==3)///查询x所属森林的大小
            {
                scanf("%d",&x);
                x=id[x];x=getfa(x);
                printf("%d\n",siz[x]);
            }
            else///查询 X 与 Y 是否在同一个森林
            {
                scanf("%d%d",&x,&y);
                x=id[x];y=id[y];
                x=getfa(x);y=getfa(y);
                if (x==y) printf("YES\n");
                else printf("NO\n");
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值