正题
题目大意
一棵树一个人从sss开始,有两个追击者从p,qp,qp,q出发,
在3k+1s3k+1\ s3k+1 s,那个人走
在3k+2和3k+3s3k+2和3k+3\ s3k+2和3k+3 s,追击者走。
求那个人最久多久不会被追上。
解题思路
首先计算出每个点距离两个追击者和那个人的距离。
然后从那个人的位置出发开始dfsdfsdfs最终被追上的位置(注意可以在一个地方等待追击者)
然后对一个点若这个点追击者比他更早到达那么就不能走,不然就统计答案后继续走。
OverOverOver
codecodecode
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=201000;
struct node{int to,next;
}a[N*2];
int n,s,q,p,dis[3][N],ls[N],ans,tot;
void addl(int x,int y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
void count_dis(int x,int fa,int id)
{for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;dis[id][y]=dis[id][x]+1;count_dis(y,x,id);}
}
void dfs(int x,int fa)
{if(dis[0][x]*2>min(dis[1][x],dis[2][x]))return;int len=min(dis[1][x],dis[2][x]);ans=max(ans,(len-1)/2*3+3-len%2);for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;dfs(y,x);}
}
int main()
{//freopen("track.in","r",stdin);//freopen("track.out","w",stdout);scanf("%d%d%d%d",&n,&s,&q,&p);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}count_dis(s,s,0);count_dis(q,q,1);count_dis(p,p,2);dfs(s,s);printf("%d",ans);
}