URAL - 1742

题目链接:URAL - 1742


显然,最小次数就是入度为0的点+单独环的个数。

最多的个数就是:每个环只能贡献一次,答案就为n - 所有环的大小 + 环的个数。

我们直接DFS找环即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
//#define int long long
using namespace std;
const int N=1e5+10;
int n,vis[N],res,to[N],mark[N],deg[N],cnt,dp[N],num,col;
void dfs(int x){
	if(mark[x]) return ;
	mark[x]=1;	dfs(to[x]); num++;
}
void dfs(int x,int dep){ 
	vis[x]=1; dp[x]=dep;
	if(!vis[to[x]]) dfs(to[x],dep+1);
	else if(vis[to[x]]!=2) res+=dep-dp[to[x]];
	vis[x]=2;
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>to[i],deg[to[i]]++;
	for(int i=1;i<=n;i++) if(!deg[i]) cnt++,dfs(i);
	for(int i=1;i<=n;i++) if(!mark[i]) cnt++,dfs(i);
	for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,1);
	cout<<cnt<<' '<<n-res;
	return 0;
}

你可能感兴趣的:(URAL,图论,dfs)