POJ 1611 The Suspects( 並查集)

題目:

嚴重急性呼吸系統綜合症( SARS), 一種原因不明的非典型性肺炎,從2003年3月中旬開始被認爲是全球威脅。爲了減少傳播給別人的機會, 最好的策略是隔離可能的患者。 在Not-Spreading-Your-Sickness大學( NSYSU), 有許多學生團體。同一組的學生經常彼此相通,一個學生可以同時加入幾個小組。爲了防止非典的傳播,NSYSU收集了所有學生團體的成員名單。他們的標準操作程序(SOP)如下: 一旦一組中有一個可能的患者, 組內的所有成員就都是可能的患者。然而,他們發現當一個學生被確認爲可能的患者後不容易識別所有可能的患者。你的工作是編寫一個程序, 發現所有可能的患者。

這道題的思路十分簡單是裸的並查集:

# include<stdio.h>
# include<stdlib.h>
int b[30000],a[510][3010],f[30000],n;
int lily2(int x){//找他的祖先節點
    if(f[x]==0 ||f[x]==x)return x;
    f[x]=lily2(f[x]);
    return f[x];
}
void lily(int x,int y){//合併兩個並查集
    if(lily2(x)!=lily2(y)){
    f[lily2(x)]=lily2(y); 
   }
}
int main(){
    int m,i,j,k,ans=0;
    while(1){
        ans=0;
        scanf("%d%d",&n,&m);//讀入
        if(n==0 &&m==0)break;
        for(i=1;i<=n;i++)f[i]=i;
        for(i=1;i<=m;i++){
            scanf("%d",&k);
            scanf("%d",&a[i][1]);
            a[i][1]+=1;
            for(j=2;j<=k;j++){
                scanf("%d",&a[i][j]);
                a[i][j]+=1;//我習慣從一開始,所以每個加一
                lily(a[i][1],a[i][j]);//將在同一個小組的放進同一個並查集
            }

        }

      for(i=1;i<=n;i++)if(lily2(1)==lily2(i))ans++;//如果和零在一個並查集則可能傳染
      printf("%d\n",ans);
   }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章