4511 信息傳遞

 題目描述 Description

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


輸入描述 Input Description

輸入共 2行。

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

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

的同學的信息傳遞對象是編號爲 T i 的同學,Ti Tii

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


輸出描述 Output Description

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


樣例輸入 Sample Input

5

2 4 2 3 1


樣例輸出 Sample Output

3

數據範圍及提示 Data Size & Hint

【輸入輸出樣例 1 說明】

遊戲的流程如圖所示。當進行完第 3 輪遊戲後,號玩家會聽到 2 號玩家告訴他自己的生日,所以答案爲 3。當然,第 3 輪遊戲後,號玩家、號玩家都能從自己的消息來源得知自己的生日,同樣符合遊戲結束的條件。



對於 30%的數據,   n ≤ 200

對於 60%的數據,  n  ≤ 2500

對於 100%的數據,   n ≤ 200000


分類標籤 Tags

圖論   最小環   noip2015提高組Day1T2


代碼 

#include<iostream>
#include<algorithm>
using namespace std;
int n,t[200005],vis[200005],minn=1000000,tot,start;
//n個人,傳遞對象,是否訪問過,最小環,此環大小,環的起點
void topo(int i)
{
    if(vis[i]==1)return;   //以前計算過
    if(vis[i]==-1){start=i;tot++;return;}  //成環,遇到起點,記錄起點
    vis[i]=-1;    //訪問標誌:正在訪問
    topo(t[i]);
    if(start&&i!=start)tot++;    //在環的路上
    else if(i==start){start=0;minn=min(minn,tot);tot=0;}   //回到起點,更新最優解,停止計算
    vis[i]=1;       //已訪問過
}
int main()
{
    cin>>n;for(int i=1;i<=n;i++)cin>>t[i];
    for(int i=1;i<=n;i++)topo(i);
    cout<<minn<<endl;
    return 0;
}

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int n,to[200005],c[200005],best=10000000,num,start;

int dfs(int u)
{
	if(c[u]==1)return 0;
	if(c[u]==-1){start=u;num=1;return 1;}
	c[u]=-1;
	if(dfs(to[u]))
	{
		if(u==start){best=min(best,num);c[u]=1;return 0;}
		else {num++;c[u]=1;return 1;}
	}
	c[u]=1;
	return 0;
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%d",&to[i]);
	for(int i=1;i<=n;i++)if(!c[i])dfs(i);
	cout<<best<<"\n";
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章