原题
题目描述
土拨鼠在第 1 1 1个房间,要走到 O r a n g e Orange Orange的第 n n n个房间。这 n n n间房间之间有 n − 1 n-1 n−1条走廊,确保这 n n n个房间连通,每个走廊的长度为 1 1 1。
土拨鼠出发 t t t秒钟后, O r a n g e Orange Orange发现他发烧了。愚蠢的 O r a n g e Orange Orange以 2 m / s 2m/s 2m/s的速度跑向土拨鼠。
土拨鼠的速度为 1 m / s 1m/s 1m/s。如果他以最佳策略跑步, O r a n g e Orange Orange多久能赶上他?每秒钟土拨鼠移动一次,然后 O r a n g e Orange Orange再次移动。土拨鼠可以选择留在原地。
输入描述:
第一行包含两个整数 n n n, t t t。接下来的 n − 1 n-1 n−1行,每行包含两个整数 x x x, y y y,表示在第 x x x个宿舍和第 y y y个宿舍之间有一条走廊。
输出描述:
一个整数,表示 O r a n g e Orange Orange赶上土拨鼠的最晚可能时间。
样例
输入
7 2
1 2
2 5
5 7
5 6
3 6
3 4
输出
1
说明
After t seconds,Groundhog is in the 5th dormitory and Orange is in the 7th dormitory.
At this point,the best way for Groundhog is to goto the 2nd dormitory or the 6th dormitory.
But wherever he goes,he will be immediately caught by Orange.
思路
因为有 n n n个节点, n − 1 n-1 n−1条边,且图联通,所以可以确定这是一棵树。
//注:不知道为什么,c++11(chang++ 3.9)会段错误。c++14(g++5.4)能过。
#include
using namespace std;
const int maxn=100005;
vector<int>e[maxn];
int f[maxn],md[maxn],dep[maxn],n,t,p=1;
bool vis[maxn];
int dfs(int x,int d)
{
vis[x]=1;dep[x]=d;md[x]=d;
for(int i=0,to;i<e[x].size();i++)
{
to=e[x][i];
if(vis[to]) continue;
f[to]=x;dfs(to,d+1);md[x]=max(md[x],md[to]);
}
}
int main()
{
scanf("%d%d",&n,&t);
for(int i=1,x,y;i^n;i++)scanf("%d%d",&x,&y),e[x].push_back(y),e[y].push_back(x);
dfs(n,0);
while(t--)
{
p=f[p];
if(p==n)break;
}
int ans=min(dep[p],(md[p]+1)/2);
printf("%d\n",ans);
return 0;
}