Educational Codeforces Round 22 C The Tag Game(树的深度)

来源:互联网 发布:星空卫视直播软件下载 编辑:程序博客网 时间:2024/06/04 19:40

C. The Tag Game

time limit per test  1second

memory limit per test      256megabytes


Alice got tired of playing the tag game by the usual rules soshe offered Bob a little modification to it. Now the game should be played onan undirected rooted tree ofn vertices. Vertex1 is the root of the tree.

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

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

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

Input

The first line contains two integer numbersn andx (2 ≤ n ≤ 2·105,2 ≤ x ≤ n).

Each of the nextn - 1 lines contains two integer numbers a andb (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.

Examples

Input

4 3
1 2
2 3
2 4

Output

4

Input

5 2
1 2
2 3
3 4
2 5

Output

6

Note

In the first example the tree looks like this:

The red vertex is Alice's starting position, the blue one isBob's. Bob will make the game run the longest by standing at the vertex3 during all the game. So here are themoves:

B: stay at vertex3

A: go to vertex2

B: stay at vertex3

A: go to vertex3

In the second example the tree looks like this:

The moves in the optimal strategy are:

B: go to vertex3

A: go to vertex2

B: go to vertex4

A: go to vertex3

B: stay at vertex4

A: go to vertex4



题意:给定一颗以1为根的无向树,Alice在1节点,Bob在x节点,两人交替操作,每一次操作可以选择移动到相邻的一个节点或者不动,Bob希望两人越晚相遇越好,Alice希望越早越好,Bob先操作,问两人最后会在一共经历多少次操作后相遇?


思路一:首先Alice一定是向着x的方向去追赶Bob的,而Bob有两种选择,一种是背离1向下走,走向树的最深处,还有一种是向着1走,看看有什么岔路口可以进去(进入这个岔路口之后很深),为了解决这两种情况,我们需要用DFS搜索每个点距离根节点的距离,以及每个点对应的树的最大深度。我们只要分别计算出上面两种情况取最大值即可(第二种应特别注意回去的过程中提前相遇的情况)

#include <cstdio>#include <vector>#include <string>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define f(i,a,b) for(int i=(a);i<=(b);++i)#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn= 200005;const int mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-6;vector<int>vec[maxn];int dis[maxn];        //记录每个点到根节点的距离int deep[maxn];       //记录每个点的最大深度int fa[maxn];void dfs(int now,int pre,int step){    dis[now]=deep[now]=step;    fa[now]=pre;    for(int i=0;i<vec[now].size();i++)    {        int nex=vec[now][i];        if(nex==pre) continue;        dfs(nex,now,step+1);        deep[now]=max(deep[now],deep[nex]);    }}int main(){    int n,x;    while(~scanf("%d%d",&n,&x))    {        for(int i=1;i<=n;i++)        {            vec[i].clear();        }        int a,b;        for(int i=0;i<n-1;i++)        {            scanf("%d%d",&a,&b);            vec[a].push_back(b);            vec[b].push_back(a);        }        dfs(1,0,0);        int ans=2*deep[x];          //背离根节点跑的最大深度        int k=x;        for(int i=0;i<dis[x];i++)   //向着根节点看看有没有更优的岔路可以走        {            if(i<dis[k])            //不能在进入岔路之前相遇            {                ans=max(2*deep[k],ans);            }            else break;            k=fa[k];        }        printf("%d\n",ans);    }    return 0;}


思路二:他们相遇一定在某个叶节点,Bob和Alice都往该叶节点移动,Bob到之后保持原地不动,所以我们从1和x分别做一次dfs,处理出每个到1和x的距离,取到Alice的距离比到Bob的距离远且与Alice距离最远的叶节点,答案就是Alice到这个叶节点距离的2倍。

#include <cstdio>#include <vector>#include <string>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define f(i,a,b) for(int i=(a);i<=(b);++i)#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn= 200005;const int mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-6;vector<int>vec[maxn];int dis1[maxn],dis2[maxn];void dfs(int now,int pre,int step,int *dis){    dis[now]=step;    for(int i=0;i<vec[now].size();i++)    {        int nex=vec[now][i];        if(nex==pre) continue;        dfs(nex,now,step+1,dis);    }}int main(){    int n,x;    while(~scanf("%d%d",&n,&x))    {        for(int i=1;i<=n;i++)        {            vec[i].clear();        }        int a,b;        for(int i=0;i<n-1;i++)        {            scanf("%d%d",&a,&b);            vec[a].push_back(b);            vec[b].push_back(a);        }        dfs(1,-1,0,dis1);        dfs(x,-1,0,dis2);        int ans=0;        for(int i=2;i<=n;i++)        {            if(dis1[i]>dis2[i])            {                ans=max(ans,dis1[i]);            }        }        printf("%d\n",ans*2);    }    return 0;}