# 實作題 - 小群體 - APCS - by Peter Wang
## 題目資訊
此題為2017.3.4測驗中的題目2
###### tags: `APCS` `遞迴`
## 題目敘述
假設有*N*個人,編號由 *0* 到 *N-1*,每個人都寫下他最好朋友的編號(最好朋友有可能是他自己的編號,如果他自己沒有其他好友),在本題中,每個人的好友編號絕對不會重複,也就是說 *0* 到 *N-1* 每個數字都恰好出現一次,這種好友的關係會形成一些小群體。
例如 *N = 10*,好友編號如下:
自己編號 0 1 2 3 4 5 6 7 8 9
好友編號 4 7 2 9 6 0 8 1 5 3
0 的好友是 4,4 的好友是 6,6 的好友是 8,8 的好友是 5,5 的好友是 0,所以 0、4、 6、8、和 5就形成了一個小群體。另外,1 的好友是 7而且 7 的好友是 1,所以 1 和 7 形成另一個小群體,同理 3 和 9 是一個小群體,而 2 的好友是自己,因此他的好友是自己,因此他自己是一個小群體。總而言之在這個例子裡有4個小群體:*{0,4,6,8,5}、{1,7} 、{3,9} 、 {2}* 。
### 輸入:
第一行是一個正整數*N*,說明團體中人數。
第二行依序是 *0* 的好友編號、*1* 的好友編號 、…… 、*N-1*的好友編號。共有N個數字,包含 *0* 到 *N-1* 的每個數字恰好出現一次,數字間會有一個空白隔開。
### 輸出:
請輸出小群體的個數。
## 解題思路
isin 來記錄是否已經進去過。
跑過一次遞迴ans++,最後就能算出答案。
## 程式碼
```clike=
#include <iostream>
using namespace std;
int arr[50004];
bool isin[50004];
int ans=0;
void r(int p){
if(isin[p]==true) return;
isin[p]=true;
r(arr[p]);
}
int main(){
int n;
while(cin>>n){
for(int i=0;i<n;i++){
cin>>arr[i];
}
fill(isin,isin+n,false);
for(int i=0;i<n;i++){
if(isin[i]) continue;
r(arr[i]);
ans++;
}
cout<<ans<<endl;
}
}
```
## 資料來源
[zerojudge](https://zerojudge.tw/)
[題目敘述](https://zerojudge.tw/ShowProblem?problemid=c291)
[原題PDF檔](https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnx6c2dpdGl0aXR8Z3g6MTRmYzQ0ZTM0MzJjZTlhYQ)
## 備註
>[name=PeterWang]
>[time=Sun, Jun 13, 2021 9:58 AM]