跟踪_纪中4805_bfs

来源:互联网 发布:pop3使用的端口号 编辑:程序博客网 时间:2024/05/17 06:04

Description


这里写图片描述

Input


这里写图片描述

Output


这里写图片描述

Data Constraint


这里写图片描述

Analysis


不难发现,石神和两个陌生人的行动方式一定是最优策略
转换一下思路,考虑对于每个点,石神是否能比两个陌生人先到达
计算石神到达每个点的最早时间,以及两个陌生人到达每个点的最早时间
然后对于每个点依次判断是不是可能是最终被追上的位置即可,最迟时间也可以方便求得
这里膜一下梓豪

Code


#include <stdio.h>#include <queue>#define inf 0x7fffffff#define maxn 400001using namespace std;struct edge{int y,next;}e[maxn+1];int dis[maxn+1],ls[maxn+1],maxE=0,ans=0;int step[3]={0,2,1};void add(int x,int y){    e[++maxE]=(edge){y,ls[x]};    ls[x]=maxE;}int max(int x,int y){    return x>y?x:y;}void bfs(int st1,int st2){    queue<int>q;    for (int i=0;i<=maxn;i++)        dis[i]=inf;    q.push(st1);q.push(2);    q.push(st2);q.push(2);    dis[st1]=dis[st2]=0;    while (!q.empty())    {        int now=q.front();q.pop();        int tmp=q.front();q.pop();        for (int i=ls[now];i;i=e[i].next)            if (dis[now]+tmp<dis[e[i].y])            {                dis[e[i].y]=dis[now]+tmp;                q.push(e[i].y);                q.push(step[tmp]);            }    }}void find(int st){    queue<int>q;    q.push(st);    q.push(-2);    while (!q.empty())    {        int now=q.front();q.pop();        int d=q.front();q.pop();        ans=max(dis[now],ans);        for (int i=ls[now];i;i=e[i].next)            if (d+3<dis[e[i].y]&&d+3<dis[now])            {                q.push(e[i].y);                q.push(d+3);            }    }}int main(){    freopen("track.in","r",stdin);    freopen("track.out","w",stdout);    int n,s,a,b;    scanf("%d%d%d%d",&n,&s,&a,&b);    for (int i=1;i<n;i++)    {        int x,y;        scanf("%d%d",&x,&y);        add(x,y);        add(y,x);    }    bfs(a,b);    find(s);    printf("%d\n",ans);    return 0;}
0 0