有 nn 個同學( 編號爲 11 到 nn)正在玩一個信息傳遞的遊戲。
在遊戲裏每人都有一個固定的信息傳遞對象,其中,編號爲 nn 的同學的信息傳遞對象是編號爲 T_iTi的同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日信息告訴各自的信息傳遞對象( 注意:可能有人可以從若干人那裏獲取信息,但是每人只會把信息告訴一個人,即自己的信息傳遞對象)。 當有人從別人口中得知自己的生日時, 遊戲結束。 請問該遊戲一共可以進行幾輪?
輸入格式
輸入共 22 行。
第 11 行包含 11 個正整數 n(2 \le n \le 200000)n(2≤n≤200000),表示 nn 個人。
第 22 行包含 nn 個用空格隔開的正整數 T_1, T_2, \cdots, T_nT1,T2,⋯,Tn,其中第 ii 個整數 T_iTi 表示編號爲 ii 的同學的信息傳遞對象是編號爲 T_iTi 的同學, T_i \le nTi≤n 且 T_i \ne iTi≠i。數據保證遊戲一定會結束。
對於50%的數據 n \le 2000n≤2000。
輸出格式
輸出共 11 行,包含 11 個整數,表示遊戲一共可以進行多少輪。
樣例輸入
5 2 4 2 3 1
樣例輸出
3
//version1
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 200050;
int nex[maxn];
int visited[maxn];
int main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
for(int i = 0; i < n;)
cin >> nex[++i];
int step = 1;
int ans = 0x3f3f3f3f;
for(int i = 0; i < n;){
int cur = ++i;// 當前節點沒有被訪問過
int start = step;
while(visited[cur] == 0){
visited[cur] = step++;// 訪問當前節點
if(visited[nex[cur]] == 0){// 若下一個節點也沒被訪問過
;
}
else{// 若下一個節點已經被訪問過了
if(visited[nex[cur]] < start)// 若是這個節點不是是本次訪問訪問的, 就什麼也不做
;
else{// 若是本次訪問的, 就計算距離
ans = min(ans, visited[cur] - visited[nex[cur]] + 1);
}
}
cur = nex[cur];// 不管怎麼樣, 都要指向下一個節點
}
}
cout << ans << endl;
return 0;
}
/*這是在version1提交過之後, 簡單修改version1得到的, 形式比較緊湊
起初看到這道題的時候, 只想到了用一個set之類的容器, 去維護每個人知道的生日,
但是想想數據範圍和具體操作就感覺不行;
晚上睡覺沒睡着, 突然想到了一點思路, 每個人只會告訴其他一個人,
把這個抽象爲邊後, 就能得到一個圖, 這道題就是要求這個圖最小的環有幾個元素
樣例: 5 -> 1 -> 3
^ |
|- 4 <-
把樣例抽象, 大約是這樣
後來發現, 這是NOI的一道題, 別人的思路是dfs,
我後來想了想, 我的代碼也是dfs, 思路還是不清晰.
*/
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 200050;
int nex[maxn];
int visited[maxn];
int main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
for(int i = 0; i < n;)
cin >> nex[++i];
int step = 1;
int ans = 0x3f3f3f3f;
for(int i = 0; i < n;){
int cur = ++i;// 當前節點沒有被訪問過
int start = step;
while(visited[cur] == 0){
visited[cur] = step++;// 訪問當前節點
if(visited[nex[cur]] != 0){// 如果next指向的節點已經被訪問過
if(visited[nex[cur]] >= start){// 如果是這次訪問的, 就說明, 形成環路了
ans = min(ans, visited[cur] - visited[nex[cur]] + 1);
}
}
cur = nex[cur];// 不過怎樣, 都要把cur = next[cur]
}
}
cout << ans << endl;
return 0;
}