The Tag Game
题 意:给你一颗无向树,n个节点,n-1条边,1号节点是跟小明在一号节点,小红在x号节点。小明想经可能快的找到小红,小红想经可能慢的让小明找到。小明小红轮流操作,每次操作,或者向相邻节点移动,或者停留在原地。问最多需要多少次操作。
数据范围:
2<=n<=2e5+5
2<=x<=n
输入样例:
4 3
1 2
2 3
2 4
输出样例:
4
思 路:小明小红一定会在某一点y相遇,在y这一点,小红到达的时间小于小明,并且这一点离小明经可能运,这样操作数最大。
收 获:收获了更多解决图论题的姿势
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int maxn = 2e5+5;
const int INF = 0x3f3f3f3f;
struct edge{
int to,cost;
};
vector<edge>G[maxn];
int d1[maxn],d2[maxn];
int n,x;
void dijkstra(int s){
fill(d2,d2+n+1,INF);
d2[s] = 0;
priority_queue<P,vector<P> ,greater<P> > que;
que.push(P(0,s));
while(que.size()){
P p = que.top();que.pop();
int v = p.second;
if(d2[v]<p.first) continue;
for(int i=0;i<G[v].size();i++){
edge e = G[v][i];
if(d2[e.to] > d2[v] + e.cost){
d2[e.to] = d2[v] + e.cost;
que.push(P(d2[e.to],e.to));
}
}
}
}
int main(){
scanf("%d %d",&n,&x);
for(int i=1;i<n;i++){
int u,v;
scanf("%d %d",&u,&v);
G[u].push_back(edge{v,1});
G[v].push_back(edge{u,1});
}
dijkstra(1);
memcpy(d1,d2,sizeof(d2));
dijkstra(x);
int MAX = -1;
for(int i=1;i<=n;i++){
if(d1[i]>d2[i]){
MAX = max(MAX,d1[i]);
}
}
printf("%d\n",MAX*2);
return 0;
}