P2661 messaging (analog / tarjan / smallest ring)

Title Description

There are n students (numbered 1 to n) are playing a game of information transmission. Transmission of information object has a fixed per person in the game information transfer objects, which numbered i is the number of students for the Ti students.

When the game starts, each person knows only his birthday. After each round, everyone will at the same time their current knowledge of the birthday message to tell each transmission of information objects (Note: Some people can get information from a number of people there, but no one will put a message telling people that own information transfer objects). When someone discovers that her birthday from someone else, the game is over. Will the game can be a total of rounds?

Input Format

Total 2 line.

Line 1 contains a positive integer n, n represents the individual.

The first line contains 222 separated by spaces nnn positive integer T1, T2, ⋯⋯, Tn wherein Ti represents an integer of i-th number of information transmission target students i is the number of students is Ti, Ti ≤n and Ti ≠ i.

Output Format

An integer representing the number of games altogether may be round.

Input # 1

5
2 4 2 3 1

Output # 1

3

Description / Tips

For 30% of the data, n≤200;

For 60% of the data, n≤2500;

To 100% of the data, n≤200000.

Meaning of the questions is very simple, find the smallest ring.
Zbw never been a graceful man, to face any problem zbw only violence will do!
Fortunately, zbw or little brain, TA realize that violence will lead to a simple n ^ 2 of T time complexity will fall, so the TA to do a simple pruning optimization, that is, no longer have to find points that constitute the ring. so with the following code.

ACCODE1

#include <iostream>
#include <cstring>
#define MAX 200020
using namespace std;
int way[MAX];
int flag[MAX];
int vis[MAX];
int dfs(int s,int now,int k)
{
	int v=way[now];
	if(now==s&&k!=0) 
	{
		flag[now]=k;
		return k;
	}
	if(vis[v]||flag[v]) return 0;
	vis[v]=1;
	flag[now]=dfs(s,v,k+1);
	return flag[now];
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>way[i];
	int ans=MAX;
	for(int i=1;i<=n;i++)
	{
		if(flag[i]==0)
		{
			memset(vis,0,sizeof(vis));
			int m=dfs(i,i,0);
			if(m!=0)
			ans=min(ans,m);
		}
	}
	cout<<ans;
	return 0;
}

Yes, you read right, so rough the AC code, zbw began to wonder exactly how much data the topic and artificial water. Like the above case zbw poor brains to write optimized almost no effect .
watching other people's time 200MS, zbw holding the TA 896MS Kusi in the corner ...
in order to learn and progress, zbw decision ( brazen ) learn from other people's code. when the TA when TA see the following sentence excited again.
Here Insert Picture Description
but then I thought to find the time is O (n), but the complexity of the deleted point may be high, above the same figure as an example. so not a positive solution ...
finally zbw found a positive solution of this question, tarjan.
fact is zbw @ thought of drowning fish tarjan, but zbw too obtuse, TA has not been aware of this problem is rather special, only one point out of each side, so even into the ring, only occur in a ring inside. so a strong connected component is a rigorous ring.

ACCODE2

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#define MAX 200020
using namespace std;
int vis[MAX];
int low[MAX];
int dfn[MAX];
int way[MAX];
int cnt=0;
int ans=MAX;
stack<int> sta;
void tarjan(int u)
{
	dfn[u]=low[u]=++cnt;
	vis[u]=1;
	sta.push(u);
	int v=way[u];
	if(dfn[v]==0)
	{
		tarjan(v);
		low[u]=min(low[u],low[v]);
	}
	else
	low[u]=min(low[u],low[v]);
	if(dfn[u]==low[u])
	{
		int tmp=0;
		while(1)
		{
			tmp++;
			int k=sta.top();
			sta.pop();
			if(k==u)
			break;
		}
		if(tmp!=1)
		ans=min(tmp,ans);
	}
}

int main()
{
	ios::sync_with_stdio(false);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>way[i];
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		tarjan(i);
	}
	cout<<ans;
	return 0;
}

zbw stupid, only violence, today set a flag- future TA to do a graceful violent person!

Published 30 original articles · won praise 9 · views 1310

Guess you like

Origin blog.csdn.net/Zhang_sir00/article/details/100565523