---
# System prepended metadata

title: 實作題 - 小群體 - APCS - by Peter Wang
tags: [遞迴, APCS]

---

# 實作題 - 小群體 - 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]