zoukankan      html  css  js  c++  java
  • 洛谷 P2921 在农场万圣节

    https://www.luogu.org/problemnew/show/P2921

    开始感觉这题30行代码就可以搞定,还是太菜啦,还是乖乖地写了tarjan。

    对图进行缩点,那么这个强联通分量中的点多余一个,那么这个环中的每个点的最长路径就是这个环(因为每个点只有一条连出去的有向边)。

    对于不在环中的点,每个点搜索,当搜到一个环时,直接返回这个环中点的个数,搜不到环返回1.

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int n,m,a[100006],ans[100006],sum[100006];
    bool vis[100006];
    int low[100006],dfn[100006],Index;
    bool in[100006];
    int stack[100006],top;
    int belong[100006],cnt;
    void tarjan(int u)
    {
        low[u]=dfn[u]=++Index;
        in[u]=1;stack[++top]=u;
        if(a[u])
        {
            int v=a[u];
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(in[v]&&low[u]>dfn[v])low[u]=dfn[v];
        }
        if(low[u]==dfn[u])
        {
            int p;
            ++cnt;
            do
            {
                p=stack[top--];
                belong[p]=cnt;
                in[p]=0;
            }while(p!=u);
        }
    }
    int dfs(int x)
    {
        if(ans[x])return ans[x];
        ans[x]=1;
        if(a[x])ans[x]+=dfs(a[x]);
        return ans[x];
    }
    int main()
    {
        int x;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==i)ans[i]=1;
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        for(int i=1;i<=n;i++)sum[belong[i]]++;
        for(int i=1;i<=n;i++)
            if(sum[belong[i]]>1)ans[i]=sum[belong[i]];
        for(int i=1;i<=n;i++)
            if(!ans[i])dfs(i);
        for(int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    页面性能
    js运行机制
    渲染机制
    通信类
    js面向对象 继承
    原型
    [HEOI2016/TJOI2016]求和
    「NOIP2018 保卫王国」
    「LGP4719【模板】动态dp」
    多项式进阶操作
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9675116.html
Copyright © 2011-2022 走看看