C. The Tag Game【dfs】

本文介绍了一种利用树形结构与并查集解决特定路径问题的方法。通过建立以1为根节点的树,并计算各节点到根节点的距离及树的直径,实现了两点间的最短路径模拟。该算法适用于寻找两点间可达的最大距离。

题目链接

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

#include <bits/stdc++.h>
#define max_n 200010
using 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 7
1 2
2 3
7 3
4 3
4 6
4 5
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值