The Tag Game CodeForces - 813C

Alice got tired of playing the tag game by the usual rules so she offered Bob a little modification to it. Now the game should be played on an undirected rooted tree of n vertices. Vertex 1 is the root of the tree.

Alice starts at vertex 1 and Bob starts at vertex x (x ≠ 1). The moves are made in turns, Bob goes first. In one move one can either stay at the current vertex or travel to the neighbouring one.

The game ends when Alice goes to the same vertex where Bob is standing. Alice wants to minimize the total number of moves and Bob wants to maximize it.

You should write a program which will determine how many moves will the game last.

Input
The first line contains two integer numbers n and x (2 ≤ n ≤ 2·105, 2 ≤ x ≤ n).

Each of the next n - 1 lines contains two integer numbers a and b (1 ≤ a, b ≤ n) — edges of the tree. It is guaranteed that the edges form a valid tree.

Output
Print the total number of moves Alice and Bob will make.

大概题意

有一个节点数为n的树,一共有n-1条边连接着,刚开始的时候小A在节点1,小B在节点x,每一次小A和小B可以移动到相邻的节点上去,当小A和小B站在相同的节点上的时候,游戏结束,小A想走最短的路,小B想走最远的路,问你游戏结束的时候小A和小B的总步数是多少(小B原地不动也算一步)

思路

因为小A想走最近的路,所以小A一定跟着小B走,并且没有多余的步数追小B,最后他们两个一定相遇在某个节点y,并且是小B先到小A后到,而小B可以找到他能走到的离根节点1距离最大的点这样就能使最后步数最大。
所以我们可以求出从1节点也就是小A起始的位置到每个节点的距离,在求出x节点到每个节点的距离,取出小A比小B晚到的点中选出离节点1的最远的那个点
因为小B不走也算一步没所以最后的结果小A走的步数和小B走的步数是一样的,直接让求出的符合题意的最远距离乘2就行

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int v,nex;
};
node e[500005];
int f[200005],vis[200005],tot;
int d1[200005],d2[200005];
void add(int u,int v)
{
    e[tot].v=v;
    e[tot].nex=f[u];
    f[u]=tot++;
}
void dfs1(int u,int fa,int sum)
{
    d1[u]=sum;
    for(int i=f[u];i!=-1;i=e[i].nex)
    {
        int v=e[i].v;
        if(v!=fa)
        {
            vis[v]=1;
            dfs1(v,u,sum+1);
        }
    }
}
void dfs2(int u,int fa,int sum)
{
    d2[u]=sum;
    for(int i=f[u];i!=-1;i=e[i].nex)
    {
        int v=e[i].v;
        if(v!=fa)
        {
            vis[v]=1;
            dfs2(v,u,sum+1);
        }
    }
}
int main()
{
    memset(f,-1,sizeof(f));
    tot=0;
    int n,m,x,y;
    scanf("%d %d",&n,&m);
    for(int i=1;i<n;i++)
    {
        scanf("%d %d",&x,&y);
        add(x,y);
        add(y,x);
    }
    memset(vis,0,sizeof(vis));
    vis[1]=1;
    dfs1(1,0,0);

    memset(vis,0,sizeof(vis));
    vis[m]=1;
    dfs2(m,0,0);
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(d1[i]>d2[i])
        {
            sum=max(sum,2*d1[i]);
        }
    }
    printf("%d\n",sum);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值