LG2921 [USACO2008DEC] Trick or Treat on the Farm ring within the tree

Problem Description

LG2921


answer

Found a total of \ (n-\) points, each point out only one side, i.e. only \ (n-\) edges, so that a ring within the tree.

\ (\ mathrm {Tarjan} \ ) condensing point.

But the problem is that there are relatively insignificant since the ring.

It follows that a strong link component \ (I \) is the condition that the ring \ (size_i>. 1 \) .

Then remember for hidden answers, especially since the judgment ring.


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') ch=getchar(),fh=-1;
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=100007;

int n;
int son[maxn],fa[maxn];

int dfn[maxn],low[maxn],ind;
bool ins[maxn];
int sta[maxn],top;

int bel[maxn],cnt;
int size[maxn];
int spe;

void tarjan(int x){
    dfn[x]=low[x]=++ind,ins[x]=1,sta[++top]=x;
    if(dfn[son[x]]){
        if(ins[son[x]]) low[x]=min(low[x],dfn[son[x]]);
    }
    else{
        tarjan(son[x]);
        low[x]=min(low[x],low[son[x]]);
    }
    if(dfn[x]==low[x]){
        ++cnt;
        while(sta[top]!=x){
            bel[sta[top]]=cnt;
            ins[sta[top]]=0;--top;
            ++size[cnt];
        }
        ++size[cnt];
        ins[x]=0,bel[x]=cnt;--top;
    }
}

int ans[maxn];

int dfs(int x){
    if(size[bel[x]]>1) return ans[x]=size[bel[x]];
    if(ans[x]) return ans[x];
    return ans[x]=dfs(son[x])+1;
}

int main(){
    read(n);
    for(int i=1;i<=n;i++){
        read(son[i]);fa[son[i]]=i;
        if(son[i]==i) ans[i]=1;
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]) tarjan(i);
        if(size[bel[i]]>1) spe=bel[i];
    }
    for(int i=1;i<=n;i++){
        if(!ans[i]) dfs(i);
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/liubainian/p/11700099.html