[agc005e]Sugigma: The Showdown

Preface

To know how to judge - 1, it's much easier to do next.

The main idea of the topic

A picture with red and blue edges is a tree with only red or blue edges.
Now A and B are initially at the same point, taking turns, A operates first.
A You can walk to another node at a time without moving or along the adjacent red edge.
B Similar, but only on the blue side.
A and B meet the end of the game.
A maximizes the game time, B minimizes the game time, if A is never caught by B at output-1.

practice

When A reaches the end of the edge (x,y) of a mangrove tree (this edge satisfies the distance between X and Y in the blue tree is greater than 2), B has not caught A, obviously it is - 1.
It was found that except for this case, A would be caught, because only the edges 1 and 2 were left.
Taking the initial point of B as the root, it is found that every time A runs to the sub-tree, or to his brother, or to his father. As long as step B dives, you can catch A. When A and B are 1 apart, A cannot escape by running up or toward his brother (the next step for his father is also caught).
Delete the edges of the mangrove that satisfy A once it arrives at - 1, and then do bfs to find the point where A can run (that is, it won't be caught by B before reaching that point). A will choose to be the deepest in the blue tree, and then stay there to abandon treatment.

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
int h[maxn],go[maxn*4],nxt[maxn*4],co[maxn*4],e[maxn][2];
int dfn[maxn],low[maxn],dep[maxn],d[maxn],dl[maxn],fa[maxn];
bool bz[maxn],pd[maxn];
int i,j,k,l,t,n,m,x,y,tot,top,ans,head,tail;
void add(int x,int y,int z){
    go[++tot]=y;
    co[tot]=z;
    nxt[tot]=h[x];
    h[x]=tot;
}
void dfs(int x,int y){
    fa[x]=y;
    dfn[x]=++top;
    int t=h[x];
    while (t){
        if (co[t]&&go[t]!=y){
            dep[go[t]]=dep[x]+1;
            dfs(go[t],x);
        }
        t=nxt[t];
    }
    low[x]=++top;
}
bool check(int x,int y){
    if (dfn[x]>dfn[y]) swap(x,y);
    if (dfn[x]<=dfn[y]&&low[x]>=low[y]) return dep[y]-dep[x]>2;
    if (fa[x]==fa[y]) return 0;else return 1;
}
void bfs(){
    int now,t;
    pd[x]=1;
    dl[tail=1]=x;
    while (head<tail){
        now=dl[++head];
        t=h[now];
        while (t){
            if (!co[t]&&!pd[go[t]]){
                d[go[t]]=d[now]+1;
                if (d[go[t]]<dep[go[t]]){
                    pd[go[t]]=1;
                    dl[++tail]=go[t];
                }
            }
            t=nxt[t];
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&x,&y);
    fo(i,1,n-1){
        scanf("%d%d",&j,&k);
        //add(j,k,0);add(k,j,0);
        e[i][0]=j;e[i][1]=k;
    }
    fo(i,1,n-1){
        scanf("%d%d",&j,&k);
        add(j,k,1);add(k,j,1);
    }
    dfs(y,0);
    fo(i,1,n-1){
        j=e[i][0];k=e[i][1];
        if (check(j,k)) bz[j]=bz[k]=1;
        else{
            add(j,k,0);
            add(k,j,0);
        }
    }
    bfs();
    fo(i,1,n){
        if (pd[i]&&bz[i]){
            printf("-1\n");
            return 0;
        }
        else if (pd[i]) ans=max(ans,dep[i]*2);
    }
    printf("%d\n",ans);
}

Posted by bluebutterflyofyourmind on Fri, 08 Feb 2019 11:03:17 -0800