Hust oj 1160 吸血鬼(並查集)

吸血鬼
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 364(173 users) Total Accepted: 213(166 users) Rating: Special Judge: No
Description

    Remilia是《東方紅魔館》中首次亮相的吸血鬼角色,是有着500歲年齡的吸血鬼領主。作爲紅魔館的主人,有着高貴和威嚴的氣質,不過也經常任性和孩子氣。關於吸血鬼有很多傳說。吸血鬼是一個血族,有着嚴格的等級。吸血鬼會嚴格聽從血之主人的命令。因此吸血鬼中的真祖可以以血之盟約命令足下的所有家臣。
    如今在某地出現了一隻吸血鬼,凡是跟吸血鬼解除的人,都有可能成爲吸血鬼。現在知道每天晚上都有哪些人互相接觸過了,那麼最多可能會有多少吸血鬼呢。假設第一隻吸血鬼的編號爲0。

Input

有多組數據,每組數據第一行有兩個整型數據n和m。分別表示一共有n個人,已經m個夜晚的活動情況。(0 < n <= 30000,0 <= m <= 500)
接下來的m行表示每晚的活動情況。每行第一個整型數據k表示當晚有多少人活動,接下來的k個數據表示當時在場人的編號。
n和m均爲0表示數據輸入結束。

Output

每一行輸出一個符合題意的答案。

Sample Input

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2

200 2
1 5
5 1 2 3 4 5
 
1 0
 
0 0
Sample Output

4
1
1

Hint

每個夜晚沒有順序

看題意很明顯是用並查集,每個夜晚沒有順序這塊我也是想了一會,之前單純的想把所有人都維護在一個集合裏,後來想到,把每一個夜晚都當做一個集合,當兩個集合中的成員發生merge時,不就相當於聯繫起兩個集合了麼,然後再find(0)就好了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Maxn = 30005;
int set[Maxn];
int n,m,x,y;
int a[Maxn];

void init()
{
    for(int i=0;i<n;i++)
    {
        set[i] = i;
    }
}

int find(int x)
{
    int r = x;
    while(set[r] != r)
        r = set[r];
    int i = x,j;
    while(i != r)
    {
        j = set[i];
        set[i] = r;
        i = j;
    }
    return r;
}

void merge(int x,int y)
{
    int fx = find(x),fy = find(y);
    if(fx != fy)
        set[fx] = fy;
}

int main()
{
    while(~scanf("%d%d",&n,&m) && (n+m))
    {
        int ans = 0;
        init();
        for(int i=0;i<m;i++)
        {
            scanf("%d",&x);
            int flag = 0;
            for(int i=0;i<x;i++)
            {
                scanf("%d",&a[i]);
            }
            for(int i=1;i<x;i++)
            {
                merge(a[0],a[i]);
            }
        }
        int LIS = find(0);
        for(int i=0;i<n;i++)
        {
            if(find(i) == LIS)
                ans++;
        }
        printf("%d\n",ans);

    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章