1. 程式人生 > >舞會3(同刻錄光盤,並查集)

舞會3(同刻錄光盤,並查集)

find 多少 lan amp spa 方案 item class eof

描述

Victoria是一位頗有成就的藝術家,他因油畫作品《我愛北京天安門》聞名於世界。現在,他為了報答幫助他的同行們,準備開一個舞會。

Victoria準備邀請n個已經確定的人,可是問題來了:
這n個人每一個人都有一個小花名冊,名冊裏面寫著他能夠通知到的人的名字。比如說在A的人名單裏寫了B,那麽表示A能夠通知到B;但是B的名單裏不見的有A,也就是說B不見得通知到A。

Victoria覺得需要確定自己需要通知多少個人m,能夠實際將所有人n都通知到。並求出一種方案以確定m的最小值是多少。

註意:自己的名單裏面不會有自己的名字。Victoria可以自身通知到所有n個人。

格式

輸入格式

第一行一個數n。接下來n行,每i+1行表示編號為i的人的小花名冊名單,名單以0結束。\

1<=n<=200。

輸出格式

一個數,m。

樣例1

樣例輸入1

18
0
11 0
0
0
0
16 0
14 0
0
0
0
2 13 0
0
11 0
7 0
0
6 0
0
0
Copy

樣例輸出1

14
解題思路:
典型並查集;
註意輸入部分;
vijos上數據沒過,原因未知,自己看看就行;
源代碼:
#include<bits/stdc++.h>
int n,m,cnt=0;
int father[220];
bool vis[220];
int find(int x)
{
    if(x!=father[x])
    father[x]=find(father[x]);
    return father[x];
}
int main() { scanf("%d",&n); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) father[i]=i; for(int i=1;i<=n;i++) { do { scanf("%d",&m); int tt=find(i); if(m!=0&&vis[m]==false&&find(i)!=find(m)) { vis[m]
=true; father[m]=tt; } } while(m!=0);} for(int i=1;i<=n;i++) if(father[i]==i) cnt++; printf("%d",cnt); }

舞會3(同刻錄光盤,並查集)