创世纪

  • 基环树上的环形DP
  • 两次DP,一次断开,一次强制连接
点击查看代码
#include <bits/stdc++.h>
using namespace std;
vector<int>z[500005];
int n,m,c[1000005];
bool b[2000005],v[1000005];
int f[1000005][2],r[1000005];
int pd;
int h[2000005],nx[2000005],t[2000005],cnt;
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		if(cc=='-')
		{
			break;
		}
		cc=getchar();
	}
	bool f=false;
	int s=0;
	if(cc=='-')
	{
		f=true;
	}
	else
	{
		s=cc-48;
	}
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	if(f==true)
	{
		s=-s;
	}
	return s;
}
void add(int u,int v)
{
	cnt++;
	nx[cnt]=h[u];
	h[u]=cnt;
	t[cnt]=v;
}
int dfs(int n1)
{
	bool f=false;
	v[n1]=true;
	for(int i=h[n1];i!=0;i=nx[i])
	{
		int q=t[i];
		if(b[i]==false)
		{
			b[i]=true;
			if(i>n)
			{
				b[i-n]=true;
			}
			else
			{
				b[i+n]=true;
			}
			if(v[q]==false)
			{
				int tmp=dfs(q);
				if(tmp>0)
				{
					if(c[n1]==tmp)
					{
						f=true;
					}
					c[n1]=tmp;
				}
			}
			else
			{
				m++;
				c[n1]=m;
				c[q]=m;
			}
		}
	}
	if(c[n1]>0)
	{
		z[c[n1]].push_back(n1);
	}
	if(f==true)
	{
		return 0; 
	}
	return c[n1];
}
void dp(int n1,int fa)
{
	f[n1][0]=0;
	f[n1][1]=1;
	int minn=INT_MAX;
	for(int i=h[n1];i!=0;i=nx[i])
	{
		int q=t[i];
		if(b[i]==false&&q!=fa)
		{
			dp(q,n1);
			f[n1][0]+=max(f[q][0],f[q][1]);
			f[n1][1]+=max(f[q][0],f[q][1]);
			minn=min(minn,max(f[q][0],f[q][1])-f[q][0]);
		}
	}
	if(n1!=pd)
	{
		if(minn==INT_MAX)
		{
			f[n1][1]=-1000000;
		}
		else
		{
			f[n1][1]=f[n1][1]-minn;
		}
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		r[i]=read1();
		add(i,r[i]);
	}
	for(int i=1;i<=n;i++)
	{
		add(r[i],i);
	}
	for(int i=1;i<=n;i++)
	{
		if(!v[i])
		{
			int tmp=dfs(i);
		}
	}
	memset(b,false,sizeof(b));
	int sum=0;
	for(int i=1;i<=m;i++)
	{
		int ans=0;
		b[z[i][0]]=b[z[i][0]+n]=true;
		pd=0;
		dp(z[i][0],0);
		ans=max(f[z[i][0]][0],f[z[i][0]][1]);
		
		pd=r[z[i][0]];
		dp(z[i][0],0);
		ans=max(ans,f[z[i][0]][0]);
		sum+=ans;
	}
	cout<<sum<<endl;
	return 0;
}
posted @ 2024-01-22 15:05  D06  阅读(3)  评论(0编辑  收藏  举报