首页 > 其他 > 详细

AT2663 Namori Grundy

时间:2019-05-03 13:18:21      阅读:141      评论:0      收藏:0      [点我收藏+]

题目描述:

luogu

题解:

好多细节,比如说每个点有且仅有一条入边。

所以说这个图一定是一个基环外向树。

考虑只是一个环的情况,我们可以发现,当环长为偶数时我们可以$01$交替染色,但环长为奇数时没有合法方案。

而且不在环上的点的$a$值是可以直接求的。

所以只需要考虑环为奇数的基环树的环上的点

当环上所有点的$a$值都相同时才会卡死。

代码:

技术分享图片
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 200050;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){c=c*10+ch-0;ch=getchar();}
    x = f*c;
}
int n,fa[N],hed[N],cnt;
struct EG
{
    int to,nxt;
}e[N];
void ae(int f,int t)
{
    e[++cnt].to = t;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
bool cir[N];
int sta[N],tl;
void get_cir()
{
    int u = 1;
    while(!cir[u])cir[u]=1,u=fa[u];
    memset(cir,0,sizeof(cir));
    while(!cir[u])sta[++tl]=u,cir[u]=1,u=fa[u];
}
int sg[N];
int vis[N],tim;
void dfs(int u)
{
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(!cir[to])dfs(to);
    }
    tim++;
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(!cir[to])vis[sg[to]]=tim;
    }
    sg[u]=0;
    while(vis[sg[u]]==tim)sg[u]++;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++)
    {
        read(fa[i]);
        ae(fa[i],i);
    }
    get_cir();
    int mx = -1,mn = n+1;
    for(int i=1;i<=tl;i++)
        dfs(sta[i]),mx=max(mx,sg[sta[i]]),mn=min(mn,sg[sta[i]]);
    if(mx==mn&&(tl&1))puts("IMPOSSIBLE");
    else puts("POSSIBLE");
    return 0;
}
View Code

 

AT2663 Namori Grundy

原文:https://www.cnblogs.com/LiGuanlin1124/p/10804614.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!