P2921 在农场万圣节(非递归的类似于记忆化搜索的巧妙方法||记忆化搜索||tarjan)

Posted greenofyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

 

以上是关于P2921 在农场万圣节(非递归的类似于记忆化搜索的巧妙方法||记忆化搜索||tarjan)的主要内容,如果未能解决你的问题,请参考以下文章

P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm(Tarjan+记忆化)

洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm

P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm - Tarjan+拓扑DP

p2921 Trick or Treat on the Farm

BZOJ 1589 Trick or Treat on the Farm (tarjan缩点,记忆化搜索)[Usaco 2008 Dec Gold]BZOJ计划

BZOJ 1589 Trick or Treat on the Farm (tarjan缩点,记忆化搜索)[Usaco 2008 Dec Gold]BZOJ计划