C. The Tag Game【dfs】

来源:互联网 发布:慈溪楼市每日成交数据 编辑:程序博客网 时间:2024/06/06 19:35

题目链接

思路:
建立一个树,以1为根,计算出每个点和根节点所在树的直径d1,并算出每个点距离根节点的距离d2。然后,模拟两个出发点根节点1和x点,让x点向根节点靠近,根节点向x点靠近。当根节点的步数小于x点(x点在更新,用并查集维护)到根节点距离时记录d2 * 2(可以到达的点),其余情况为不能到达。

#include <bits/stdc++.h>#define max_n 200010using namespace std;typedef long long LL;int pre[max_n], d1[max_n], d2[max_n];vector<int> v[max_n];int n, x, p1, p2;void dfs(int now, int next, int step) {    d1[now] = d2[now] = step;    pre[now] = next;    for(int i = 0; i < v[now].size(); i++) {        int temp = v[now][i];        if(temp != next) { //为了不重复,只需要不和父节点相同即可            dfs(temp, now, step + 1);            d2[now] = max(d2[now], d2[temp]);        }    }} int main() {    scanf("%d %d", &n, &x);    for(int i = 0; i < n - 1; i++) {        scanf("%d %d", &p1, &p2);        v[p1].push_back(p2);        v[p2].push_back(p1);    }    dfs(1, 1, 0);    int ans = 2 * d2[x];    int k = x;//  for(int i = 1; i <= n; i++) {//      printf("%d -> %d -> %d -> %d\n", i, d1[i], d2[i], pre[i]);//  }    for(int i = 0; i < d1[x]; i++) {    //  printf("%d -> %d -> %d\n", k, d1[k], d2[k]);        if(i < d1[k]) {            ans = max(2 * d2[k], ans);        }        else break;        k = pre[k];    }    printf("%d\n", ans);     return 0;}/*7 71 22 37 34 34 64 5*/