zoukankan      html  css  js  c++  java
  • P2921 在农场万圣节(非递归的类似于记忆化搜索的巧妙方法||记忆化搜索||tarjan)

    1、

    //秉持着必然进入一个环的思想
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100009;
    int color[N];//记录此节点的颜色(也就是是哪个节点发出的路径经过了这个节点)
    int circle[N];//记录环大小
    int dfn[N];//记录此节点的时间戳
    int indfn[N];//记录入环时间戳
    int nxt[N];//记录题目所给的下一个隔间是哪儿
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>nxt[i];
        }
        for(int cow=1;cow<=n;cow++)//循环每一只牛
        {
            for(int i=cow,cnt=0;;i=nxt[i],cnt++)
            {
                if(!color[i])//如果这个节点还没有走过
                {
                    color[i]=cow;//记录节点颜色
                    dfn[i]=cnt;//记录时间戳
                }
                else if(color[i]==cow)//如果本来就位于环内或者通过一条没人走过的路进入环内
                {
                    circle[cow]=cnt-dfn[i];//环大小为此时时间减去入环时间
                    indfn[cow]=dfn[i];//入环时间戳就是该店的时间戳(因为我们再次回到这个点的时候我们并没有对这个点的时间戳进行改动)
                    cout<<cnt<<endl;
                    break;
                }
                else//如果这个点曾经是另一条路径走过的
                {
                    circle[cow]=circle[color[i]];//环的大小复制过来
                    indfn[cow]=cnt+max(0,indfn[color[i]]-dfn[i]);//入环时间戳
                                                                //如果cow这个点在环内,那么cnt直接就是入环时间戳(max内另一项小于等于0)
                                                                //如果不在环内,算下距离
                    cout<<indfn[cow]+circle[cow]<<endl;//入环时间戳加上环的大小就是答案
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    2015第18周四
    2015第18周三程序员能力
    2015第18周二
    2015第18周一
    2015第17周日活在当下
    2015第17周六去除表中某字段重复记录
    2015第17周五
    2015第17周四
    Mac OS X Yosemite安装Hadoop 2.6记录
    GLEW_ERROR_NO_GL_VERSION的解决方法
  • 原文地址:https://www.cnblogs.com/greenofyu/p/12288861.html
Copyright © 2011-2022 走看看