求助,W50
查看原帖
求助,W50
754357
zty8426楼主2023/8/11 11:37

不知道哪里错了QAQ

#include<bits/stdc++.h>
#define re register
using namespace std;
const int N = 1e6 + 5,_inf = -999,inf = 32768,error = 10086;
int fa[N],len[N],len2[N];
int flag[N],cnt = 0,flag3[N];
bool bz;
int flag2[N];
int q[N],size = 1;
int n;
int ans,maxn,minn,last;
inline void dfs_zh(re int i)
{
	q[1] = i;size = 1;
	re int x,sizem;
	while(true)
	{
		x = q[size];
		if(flag[x] != 0)
		{
			if(flag[x] == _inf)
				++cnt,flag[x] = cnt,bz = true;
			sizem = --size;
			break;
		}
		flag[x] = _inf;
		q[++size] = fa[x];
	}
	while(true)
	{
		if(size == 0) break;
		x = q[size];
		if(flag[x] == cnt) {bz = false;--size;flag3[cnt] = sizem - size;continue;}
		if(bz) flag[x] = cnt;
		else flag[x] = -1;
		--size;
	}
}
inline void dfs_max(re int i)
{
	q[1] = i;size = 1;
	re int x;
	while(true)
	{
		x = q[size];
		if(fa[x] == x)
		{
			if(flag2[x] != error)
				flag2[x] = error,++maxn;
			bz = true;
			--size;break;
		}
		if(flag2[x] != 0)
		{
			if(flag2[x] == _inf)
				++maxn,flag2[x] = error;
			bz = true;
			--size;break;
		}
		if(bz) flag2[x] = inf,bz = false;
		else flag2[x] = _inf;
		q[++size] = fa[x];
	}
	while(true)
	{
		if(size == 0) break;
		x = q[size];
		if(flag2[x] == inf) {bz = false;--size;continue;}
		if(flag2[x] == error) {--size;continue;}
		if(bz) ++maxn,flag2[x] = error;
		--size;
	}
}
inline void dfs_min(re int x)
{
	if(flag2[fa[x]] == error || flag2[x] == error) return;
	flag2[x] = inf;--len2[x];
	++minn,--len2[fa[fa[x]]],flag2[fa[x]] = error,flag[fa[x]] = -1,len[fa[x]] = _inf;
}
int main()
{
	scanf("%d",&n);
	for(re int i = 1;i <= n;++i)
		scanf("%d",&fa[i]),++len[fa[i]];
	for(re int i = 1;i <= n;++i)
	{
		bz = false;
		dfs_zh(i);
		if(flag[i] == -1) flag3[0] = -1;
	}
	for(re int i = 1;i <= n;++i)
		if(len[i] == 0) bz = true,dfs_max(i);
	for(re int i = 1;i <= n;++i)
		if(flag[i] > 0) bz = true,dfs_max(i);
	for(re int i = 1;i <= n;++i) flag2[i] = 0;
	while(true)
	{
		last = minn;
		for(re int i = 1;i <= n;++i)
			if(len[i] == 0) dfs_min(i);
		for(re int i = 1;i <= n;++i)
			len[i] += len2[i],len2[i] = 0;
		if(last == minn) break;
	}
	for(re int i = 1;i <= n;++i)
		if(flag[i] > 0 && len[i] != _inf)
			dfs_min(i);
	if(flag3[0] != -1)
	{
		minn = 0;
		for(re int i = 1;i <= cnt;++i) minn += ceil(flag3[i] / 2.0);
	}
	printf("%d %d",minn,maxn);
	return 0;
}
2023/8/11 11:37
加载中...