牛客编程巅峰赛S1第12场 王者A-锻炼身体(树上追击问题)
题目链接:https://ac.nowcoder.com/acm/contest/6916/A
CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/108035114
题意
疫情期间,牛牛整天摊在床上沉溺于手机,身体日渐虚胖,因此牛妹拿走家中的 wifi 路由器,迫使牛牛下床来拿到路由器。在这过程中,牛牛想要在尽可能短的时间内拿到路由器,而牛妹却希望牛牛多走一会儿。现假设牛妹家中有 n 个房间,任意两个房间有且仅有一条路径,起初路由器在编号为 x 的房间内,牛牛在编号为 1 的房间内,牛牛与牛妹速度相同,当俩人同时开始移动,牛牛要经过几个房间才能拿到路由器。
只要牛牛和路由器处在同一房间,便看作牛牛已拿到路由器。
输入
第一个参数为 n ,\((1\leq n\leq 100,000)\)
第二个参数为 \(x ,(1\leq x\leq n)\)
第三个参数为大小为 \(n−1\) 的点对 \((u_i, v_i)\)的集合,其中 \((u_i, v_i)\) 表示结点 \(u_i\)与结点 \(v_i\)之间有一条边,\(1\leq u_i, v_i \leq n\)
输出
牛牛最多需要经过的房间数(包括 1 号房间在内)。
输入
5,2,[(1,2),(2,3),(3,4),(2,5)]
输出
4
说明
当牛妹将路由器放到 4 号房间时,牛牛需要经过 1 -> 2 -> 3 -> 4 共四个房间。
emmm,实际上牛妹是一定会往某个叶子节点跑的,那么我们只需要求出牛妹到每个叶子节点的距离和牛牛到每个叶子节点的距离看看是否牛妹能够先到达该叶子节点,如果可以的话就说明牛妹一定能够在牛牛之前到这里。然后我们对每个牛妹先到的叶子节点去一个牛牛的最大值就完事了。
以下是AC代码:
/**
* struct Point {
* int x;
* int y;
* };
*/
const int mac=1e5+10;
vector<int>g[mac];
int dis[mac],dist[mac];
class Solution {
public:
void dfs(int u,int fa)
{
for (auto v:g[u]){
if (v==fa) continue;
dis[v]=dis[u]+1;
dfs(v,u);
}
}
void dfs2(int u,int fa)
{
for (auto v:g[u]){
if (v==fa) continue;
dist[v]=dist[u]+1;
dfs2(v,u);
}
}
int solve(int n, int x, vector<Point>& Edge) {
if (x==1) return 0;
for (auto v:Edge){
g[v.x].push_back(v.y);
g[v.y].push_back(v.x);
}
dfs(1,0);
dfs2(x,0);
int ans=0;
for (int i=2; i<=n; i++){
if (g[i].size()==1) {
if (dis[i]>dist[i]) ans=max(dis[i],ans);
}
}
return ans+1;
}
};