Gangstar(LCA)

題目傳送門
在忙碌的ICPC訓練後, Vanis和Qiy玩起了警匪遊戲。

遊戲在一棵具有n個節點的無向樹上進行,Qiy作爲警察,想要儘早的抓到Vanis。而Vanis作爲匪徒,想要儘量逃脫Qiy的追捕。奈何“天網恢恢,疏而不漏”,即使強如Vanis,也只能儘量拖延自己被抓到的時間。

初始時,Qiy處於1號點,Vanis處於x號點。每2秒種,兩者可以選擇移動1步到相鄰的點或留在原地(按上文中提到的策略行動)。當二人在某個時間處於同一頂點時,Qiy便追到了Vanis。Vanis會盡量逃離Qiy的追逐,而Qiy想盡快追到Vanis。作爲喫瓜羣衆的選手們,你們知道Qiy最少要花多少時間才能追捕到Vanis嗎?

輸入描述:
第一行輸入兩個正整數n和x,分別表示樹的頂點個數以及Vanis初始所在的位置。
接下來n - 1行每行輸入兩個正整數u和v,表示有一條邊連接頂點u和頂點v。

.

  • 保證輸入的頂點和邊構成一棵無向樹。

輸出描述:
輸出一個整數,表示Qiy追到Vanis所需的時間。
示例1
輸入

4 3
1 2
2 3
2 4

輸出

4

說明
2s時,vanis停留在3號點,Qiy移動到2號點
4s時,vanis停留在3號點,Qiy移動到3號點,抓捕成功

思路:將頂點1視作樹根,逃跑的策略就只有兩種,一種是直接往更深的方向跑來拖延時間,另一種是先往深 度小的地方跑之後在被追捕到之前進入到更深的子樹中往深處跑拖延時間。所以只需要先通過搜索來計 算所有結點的深度,之後再搜索一次,對於逃跑者能夠到達的所有地點,計算其中耗時最大的那個即 可。

ac代碼

#include<bits/stdc++.h>
#include<bitset>
#include<unordered_map>
#define pb push_back
#define bp __builtin_popcount
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e6+100;
const int MOD=1e9+7;
int lowbit(int x){return x&-x;}
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }
int depth[500001], fa[500001][50], lg[500001];
struct node{
    int to,next;
}edge[maxn];
int head[maxn],tol;
void  add(int a,int b)
{
    edge[++tol].to=b;
    edge[tol].next=head[a];
    head[a]=tol;
}
void DFS(int u,int v)//v是u的爸爸!
{
    fa[u][0]=v;depth[u]=depth[v]+1;
    for(int i=1;(1<<i)<=depth[u];i++)
    fa[u][i]=fa[fa[u][i-1]][i-1];

    for(int i=head[u];i;i=edge[i].next)
    {
        node t=edge[i];
        if(t.to==v)//爸爸除外!
        continue;
        DFS(t.to,u);
    }
}
int LCA(int  x,int y)
{
    if(depth[x]<depth[y])swap(x,y);

    while(depth[x]>depth[y])
    {
        x=fa[x][lg[depth[x]-depth[y]]-1];
    }
    if(x==y)return x;
    for(int k=lg[depth[x]];k>=0;k--)
    {
        if(fa[x][k]!=fa[y][k])
        {
          x=fa[x][k];
          y=fa[y][k];
        }
    }
    return fa[x][0];
}
int get(int x,int y)
{
    return depth[x] + depth[y] - 2 * depth[LCA(x, y)];
}
int main()
{
    ios::sync_with_stdio(false);
    int n,x;
    cin>>n>>x;
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    for(int i = 1; i <= n; ++i)
	lg[i] = lg[i-1] + (1 << lg[i-1] == i);
    DFS(1,0);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int dis1=get(x,i)*2,dis2=get(1,i)*2;
        if(dis1<dis2)
        {
            ans=max(ans,dis2);
        }
    }
    cout<<ans<<endl;
    system("pause");
    return 0;

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