hrbust 1725 Virus Outbreaking 【并查集】

Virus Outbreaking
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 122(37 users)Total Accepted: 45(34 users)Rating: Special Judge: No
Description

Village H is suffering a virus outbreaking. 

There are n persons in the village, some of them is infected by at most one virus.


Input

There are multiple test cases. The first line is an integer T indicating the number of test cases.

The first line of each case is two positive integers n and q. n is the number of persons in the village and q is the times of event happened in village H.

The second line of each case is n numbers a1, a2, ..., an separated by space. ai stands for the kind of virus the ith person infected. 0 means not infected.

Then q lines following, each is an event happened in the village, consist of touching or query ordered by happening:

touch A B: a touched b and they infected each other. They will be together until the end.

query A: ask how many kind of virus person A infected. If A is not infected, output 0.

There will be a blank line after each case.


Note: 1 <= n <= 1000, 1 <= q <= 1000, 0 <= ai <= 32.


Output

For each query, output one line consist of all kinds of virus the person A infected, Output them  by the increasing order, separated by space.

Output a blank line after each test case.

Sample Input
2
4 6
20 14 24 30
query 1
query 4
query 4
query 4
touch 1 4
query 2
4 6
7 4 28 20
touch 4 1
query 2
query 1
query 3
query 3
query 1
Sample Output
20
30
30
30
14
4
7 20
28
28
7 20
 
 
简单并查集,重点是输出,注意查重及方法;
 
 
#include<bits/stdc++.h>
using namespace std;
int pre[1111];
int a[1111];
int n, m;
int findx(int x)
{
    return pre[x] == x ? x : pre[x] = findx(pre[x]);
}
void join(int a, int b)
{
    int X = findx(a);
    int Y = findx(b);
    if(X != Y)
        pre[X] = Y;
}
void group(int c)
{
    int ans[1111];
    int num = 0;
    for(int i = 1; i <= n; i++)
    {
        if(findx(i) == findx(c))
        {
            int flag = 1;      ///查重
            for(int j = 0; j < num; j++)
                if(ans[j] == a[i])
                    flag = 0;
            if(flag && a[i])
                ans[num++] = a[i];
        }
    }
    if(!num)
        printf("0\n");
    else
    {
        sort(ans, ans + num);
        for(int i = 0; i < num - 1; i++)
            printf("%d ", ans[i]);
        printf("%d\n", ans[num - 1]);
    }
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            pre[i] = i;
        }
        while(m--)
        {
            char order[66];
            scanf("%s", order);
            if(order[0] == 't')
            {
                int nx, ny;
                scanf("%d%d", &nx, &ny);
                join(nx, ny);
            }
            if(order[0] == 'q')
            {
                int nz;
                scanf("%d", &nz);
                group(nz);
            }
        }
        printf("\n");
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值