码迷,mamicode.com
首页 > 其他好文 > 详细

第十四届华中科技大学程序设计竞赛 C Professional Manager【并查集删除/虚点】

时间:2018-04-30 22:44:12      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:eth   turn   include   ==   mat   sam   math   print   queue   

题目描述 
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.
示例1
输入
1
10 8
3 1
4 1 2
1 1 2
3 1
4 1 2
2 1
3 1
4 1 2
输出
Case #1:
1
NO
2
YES
1
NO



题意:对trees有四种操作。


1 u v,将包含u-th树的森林和含有v-th树的森林合并在一起;

u,将u-th树与森林分开;

3 u,查询包含u-th树的森林的大小;

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

【分析】:给每个点都给他们造一个编号w,删除点,就相当于该点的编号w改变就可以了,也是相当于构造新点。

【出处】:UVA 11987 (白书267)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<string>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<set>
#define LL long long
#define INF 0xffffff
using namespace std;
const double pi = 2 * acos (0.0);
const int maxn = 2e5+10;
int n,m;
int p[maxn];
int s[maxn];
int w[maxn];
  
void init()
{
    for(int i=1;i<=maxn;i++) //这里必须是maxn,其他的好像不行
    {
        p[i] = i;
        w[i] = i;
        s[i] = 1;
    }
}
int Find(int x)
{
    return x==p[x]?x:p[x]=Find(p[x]);
}
void Union(int x,int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx!=fy)
    {
        p[fx] = fy;
        s[fy] += s[fx];
        //printf("size=%d\n",s[fy]);
    }
}
  
int main()
{
    int T;
    cin >> T;
    int k =1;
    while(T--)
    {
        printf("Case #%d:\n",k++);
        init();
       
        cin >> n >> m;
        int cnt = n;
        while(m--)
        {
            int op,u,v;
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&u,&v);
                Union(w[u],w[v]);
            }
            else if(op==2)
            {
                scanf("%d",&u);
                s[Find(w[u])]--;
                w[u] = ++cnt;
            }
            else if(op==3)
            {
                scanf("%d",&u);
                printf("%d\n",s[Find(w[u])]);
            }
            else{
                scanf("%d%d",&u,&v);
                if(Find(w[u])==Find(w[v]))
                    printf("YES\n");
                else printf("NO\n");
            }
        }
    }
    return 0;
}

第十四届华中科技大学程序设计竞赛 C Professional Manager【并查集删除/虚点】

标签:eth   turn   include   ==   mat   sam   math   print   queue   

原文地址:https://www.cnblogs.com/Roni-i/p/8974941.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!