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;
}
复制代码

 

posted on   greenofyu  阅读(256)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示