AGC005 E

題意:
n個點,n-1條紅邊,n-1條藍邊。紅邊構成一棵樹,藍邊構成一棵樹。開始時,A在點x,B在點y。兩人輪流操作,A先手。A可以不動或沿紅邊走,B可以不動或沿藍邊走。當A、B走到同一個點時遊戲結束。A想玩的儘量久,B想盡量快。問會進行多少輪,無限輸出-1。
n<=200000

#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<vector>
#define N 210000
#define pb push_back
using namespace std;
struct node{int y,nex;}a[2*N];
int e[N][2],len,fir[N],n,sa,sb,dep[N],dfn[N],las[N],id,f[N],p[N],tail,d[N],ans;
bool b[N],v[N];
vector<int> A[N];
void ins(int x,int y)
{
    a[++len].y=y;a[len].nex=fir[x];fir[x]=len;
}
void dfs(int x,int fa)
{
    f[x]=fa;
    dfn[x]=++id;
    dep[x]=dep[fa]+1;
    for(int k=fir[x];k;k=a[k].nex)
    {
        int y=a[k].y;
        if(y==fa) continue;
        dfs(y,x);
    }
    las[x]=id;
}
bool check(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    if(dfn[x]<=dfn[y] && las[x]>=dfn[y])
    {
        if(dep[y]-dep[x]>2) return 1;
        return 0;
    }
    if(f[x]==f[y]) return 0;
    return 1;
}
void bfs()
{
    v[sa]=1;p[1]=sa;tail=1;
    for(int i=1;i<=tail;i++)
    {
        int x=p[i],siz=A[x].size();
        for(int k=0;k<siz;k++)
        {
            int y=A[x][k];
            d[y]=d[x]+1;
            if(d[y]<dep[y] && v[y]==0) {v[y]=1;p[++tail]=y;}
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&sa,&sb);
    for(int i=1;i<n;i++) scanf("%d%d",&e[i][0],&e[i][1]);
    for(int i=1;i<n;i++)
    {
        int x,y;scanf("%d%d",&x,&y);
        ins(x,y);ins(y,x);
    }
    dfs(sb,0);
    for(int i=1;i<=n;i++) dep[i]--;
    for(int i=1;i<n;i++)
    {
        int x=e[i][0],y=e[i][1];
        if(check(x,y)) 
            b[x]=b[y]=1;
        else A[e[i][0]].pb(e[i][1]),A[e[i][1]].pb(e[i][0]);
    }
    bfs();
    for(int i=1;i<=n;i++) 
    {
        if(v[i] && b[i]) {printf("-1\n");return 0;}
        if(v[i]) ans=max(ans,dep[i]*2);
    }
    printf("%d\n",ans);
    return 0;
}

題解:
先把以y爲根把B的樹建出來。對於A的一條邊(x,y),x和y在B的樹上距離>2,如果A走到x或y之前或下一輪B都沒能抓到他,那答案就是-1。
把這些邊刪掉後就剩下一些1或2的邊,一個重要的結論就是A用這些邊走不出B的子樹。所以可以bfs一遍,找出A在走到那些點後還不會被B抓到。
如果不能走到-1的點,那麼A就會留在能走到的最深的點,然後放棄治療>_<
於是就可以算答案了。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章