並查集 POJ 1611

題目點這裏

題目大意

學校中有很多社團,有的學生同時加了不同的社團,現在有一種病會傳染,假設一個社團裏有一個人有被傳染的嫌疑,那麼該社團的所有人都會被傳染。
初始條件:0號學生有嫌疑,算出所有有嫌疑的學生總數。

題解

將每組輸入的學生編號使用並查集聯繫起來,然後找出0號元素的祖先,輸出個數。此處用一個輔助sum數組來統計屬於本節點的元素個數,所以最後輸出sum[find(id[0])]即爲所求。

代碼

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
const int M = 30005;
int id[M];
int sum[M];
int find(int p)
{
    while(p != id[p])   p = id[p];
    return p;
}
//bool connected(int p,int q)
//{
//  return find(p) == find(q);
//}
void unionn(int p,int q)
{
    int pRoot = find(p);
    int qRoot = find(q);
    if(pRoot != qRoot)
    {
        id[qRoot] = pRoot; //q->p 
        sum[pRoot] += sum[qRoot];
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m))
    {
//      int count = 0;
        /*if(m == 0)
        {
            printf("1\n");
            continue;
        }*/
        if(n == 0 && m == 0)
            break;
        for(int i = 0;i < n; i++) //初始化 
        {
            id[i] = i;
            sum[i] = 1;
        }
        for(int i = 0;i < m;i++)
        {
            int t;
            int p,q;
            scanf("%d",&t);
            scanf("%d",&p);
            for(int j = 1;j < t;j++)
            {
                scanf("%d",&q);
                unionn(p,q);   //依次相連,從後往前 
                p = q; 
            }
        }
        /*for(int i = 0; i < n;i++)
        {
            if(find(i) == id[0])
                ++count;
        }*/
        int x = find(id[0]);
        printf("%d\n",sum[x]);          
    }
    return 0;
 }
發佈了48 篇原創文章 · 獲贊 17 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章