1. 程式人生 > >cogs luogu 2105. [NOIP2015] 信息傳遞

cogs luogu 2105. [NOIP2015] 信息傳遞

信息 問題 傳遞對象 內存 lin 包含 最小 ons urn

★☆ 輸入文件:2015message.in 輸出文件:2015message.out 簡單對比
時間限制:1 s 內存限制:256 MB

【題目描述】

有n個同學(編號為1到n)正在玩一個信息傳遞的遊戲。在遊戲裏每人都有一個固定的信息傳遞對象,其中,編號為i的同學的信息傳遞對象是編號為Ti同學。

遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日信息告訴各自的信息傳遞對象(註意:可能有人可以從若幹人那裏獲取信息,但是每人只會把信息告訴一個人,即自己的信息傳遞對象)。當有人從別人口中得知自己的生日時,遊戲結束。請問該遊戲一共可以進行幾輪?

【輸入格式】

輸入共2行。

第1行包含1個正整數n表示n個人。

第2行包含n個用空格隔開的正整數T1,T2,……,Tn其中第i個整數Ti示編號為i

的同學的信息傳遞對象是編號為Ti的同學,Ti≤n且Ti≠i

數據保證遊戲一定會結束。

【輸出格式】

輸出共 1 行,包含 1 個整數,表示遊戲一共可以進行多少輪。

【樣例輸入】


5

2 4 2 3 1


【樣例輸出】

3

【提示】



技術分享

遊戲的流程如圖所示。當進行完第 3 輪遊戲後, 4 號玩家會聽到 2 號玩家告訴他自

己的生日,所以答案為 3。當然,第 3 輪遊戲後, 2 號玩家、 3 號玩家都能從自己的消息

來源得知自己的生日,同樣符合遊戲結束的條件。


對於 30%的數據, n ≤ 200;

對於 60%的數據, n ≤ 2500;

對於 100%的數據, n ≤ 200000。

STL過4點(真慢)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<vector>
 7 
 8 using namespace std;
 9 const int
N=200010; 10 11 vector<int>v[N]; 12 vector<int>VV[N]; 13 int nxt[N]; 14 15 inline int read() 16 { 17 int x=0; 18 char c=getchar(); 19 while(c<0||c>9)c=getchar(); 20 while(c>=0&&c<=9)x=x*10+c-0,c=getchar(); 21 return x; 22 } 23 24 int main() 25 { 26 freopen("2015message.in","r",stdin); 27 freopen("2015message.out","w",stdout); 28 29 int n=read(); 30 for(int i=1;i<=n;i++) 31 { 32 int x=read(); 33 nxt[i]=x; 34 v[i].push_back(i); 35 } 36 37 for(int i=1;;i++) 38 { 39 for(int j=1;j<=n;j++) 40 { 41 for(int k=0;k<v[j].size();k++) 42 { 43 if(v[j][k]==nxt[j]) 44 { 45 printf("%d",i); 46 return 0; 47 } 48 VV[nxt[j]].push_back(v[j][k]); 49 } 50 } 51 for(int j=1;j<=n;j++) 52 { 53 for(int k=0;k<VV[j].size();k++) 54 v[j].push_back(VV[j][k]); 55 VV[j].clear(); 56 } 57 } 58 59 return 0; 60 }

向圖的最小環問題,深搜遍歷解決(AC):

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 
 6 using namespace std; 
 7 
 8 
 9 int Roa[200001];
10 int Jud[200001];
11 int Hui[200001];
12 int N,M=300000;
13 
14 inline int read()
15 {
16     int x=0;
17     char c=getchar();
18     while(c<0||c>9)c=getchar();
19     while(c>=0&&c<=9)x=x*10+c-0,c=getchar();
20     return x;
21 }
22 
23 void Dfs(int k)
24 {
25     if(Hui[ Roa[k] ]||Jud[k])//be search again
26     {
27         if(Hui[ Roa[k] ])
28             M=min(M,Hui[k]-Hui[ Roa[k] ]+1);
29     }
30     else
31     {
32         Jud[k]=1;//pan duan cong ci dian dao da de dian zhi qian shi fou dao guo
33         Hui[ Roa[k] ]=Hui[k]+1;//k->Roa[k]->Roa[Roa[k]]... 
34         Dfs(Roa[k]);
35         Hui[ Roa[k] ]=0;//回溯    
36     }
37 }
38 
39 int main()
40 {
41     freopen("2015message.in","r",stdin);
42     freopen("2015message.out","w",stdout);
43     N=read();
44     for(int i=1;i<=N;i++)
45     {
46         Roa[i]=read();//a->Roa[a]
47         Jud[i]=0;//pan duan
48         Hui[i]=0;
49     }
50     for(int i=1;i<=N;i++)
51         if(!Jud[i])//had not found himself,可無,沒用
52             Dfs(i);
53             
54     printf("%d",M);
55     
56     return 0;
57 }

cogs luogu 2105. [NOIP2015] 信息傳遞