https://ac.nowcoder.com/acm/contest/3007/B

 

此题我不但又双叒叕做麻烦了,而且达到了我麻烦的巅峰

tarjan重构图然后新图上拓扑dp

吐血。。。

 

因为他是n个点n条边,且每个点只有一条出边

所以该图是一个基环内向树

从一个点出发,要么走到链的一段,要么停在一个环上

只需要记忆化dfs找出那个环即可

注意可能有自环

稍稍借鉴了一下tarja的思路

 

#include<cstdio>
#include<algorithm>
 
using namespace std;

#define N 1000001
 
int to[N],f[N]; 
bool vis[N];

int dfn[N],tim;

int sum,tag;

void dfs(int x)
{
    vis[x]=true;
    dfn[x]=++tim;
    if(!dfn[to[x]]) 
    {
        dfs(to[x]);
        if(tag) 
        {
            f[x]=sum;
            if(tag==x) tag=0;
        }
        else f[x]=f[to[x]]+1;
    }
    else if(vis[to[x]]) 
    {
        sum=dfn[x]-dfn[to[x]]+1;
        f[x]=sum;
        tag=to[x];
        if(x==tag) tag=0;
    }
    else f[x]=f[to[x]]+1;
    vis[x]=false;
}

int main()
{
     int n;
     scanf("%d",&n);
     for(int i=1;i<=n;++i) scanf("%d",&to[i]);
     for(int i=1;i<=n;++i) 
         if(!dfn[i]) dfs(i);
     int ans=0;
     for(int i=1;i<=n;++i) ans=max(ans,f[i]);
     printf("%d",ans);
}

 

相关文章:

  • 2021-10-05
  • 2021-12-16
  • 2021-10-21
  • 2021-11-10
  • 2022-03-04
  • 2021-09-22
  • 2021-09-26
  • 2021-10-04
猜你喜欢
  • 2021-05-22
  • 2021-07-12
  • 2022-02-07
  • 2021-07-20
  • 2021-12-18
  • 2021-05-29
  • 2022-02-03
相关资源
相似解决方案