P2921 [USACO08DEC]Trick or Treat on the Farm G(Targan)
Posted xcfxcf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2921 [USACO08DEC]Trick or Treat on the Farm G(Targan)相关的知识,希望对你有一定的参考价值。
https://www.luogu.com.cn/problem/P2921
#include<bits/stdc++.h> using namespace std; const int Maxn=100005; int nxt[Maxn]; int ans[Maxn]; int head[Maxn],cnt; struct road{ int to,next; }e[Maxn*2]; void add(int a,int b){ cnt++; e[cnt].to=b; e[cnt].next=head[a]; head[a]=cnt; } int sum,color[Maxn],low[Maxn],ins[Maxn],tim[Maxn],sta[Maxn],top=1,col; int Lemon[Maxn]; void Tarjan(int x){ tim[x]=low[x]=++sum; sta[top++]=x; ins[x]=1; for(int i=head[x];i!=0;i=e[i].next){ if(ins[e[i].to]==0){ Tarjan(e[i].to); low[x]=min(low[x],low[e[i].to]); } else if(ins[e[i].to]==1) low[x]=min(low[x],tim[e[i].to]); } if(tim[x]==low[x]){ col++; do{ color[sta[--top]]=col; ins[sta[top]]=-1; }while(sta[top]!=x); } return ; } void search(int root,int x,int step){ if(ans[x]!=0) { ans[root]=ans[x]+step; return ; } else search(root,nxt[x],step+1); } int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ scanf("%d",&nxt[i]); add(i,nxt[i]); if(nxt[i]==i) ans[i]=1;//注意特判环为1的情况。 } for(int i=1;i<=n;i++) if(ins[i]==0) Tarjan(i); for(int i=1;i<=n;i++) Lemon[color[i]]++;//记录环的大小 for(int i=1;i<=n;i++) if(Lemon[color[i]]!=1) ans[i]=Lemon[color[i]];//处理在环内的点 for(int i=1;i<=n;i++) if(ans[i]==0) search(i,nxt[i],1);//处理在环外的点。 for(int i=1;i<=n;i++) printf("%d ",ans[i]); return 0; }
以上是关于P2921 [USACO08DEC]Trick or Treat on the Farm G(Targan)的主要内容,如果未能解决你的问题,请参考以下文章
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm(Tarjan+记忆化)
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm - Tarjan+拓扑DP
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 记忆化搜索dfs
Luogu 2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm