Codeforce 813C 思维题

传送门:题目

题意:

一棵树,两个点,一个点a想尽快靠近另一个点b,一个点想尽快远离一个点,问这两个点走多少步能碰上。

题解:

因为是一棵树,所以不存在环,一定有解。再脑补一下过程,肯定是:尽快靠近的那个点每一步都是沿最短路径靠近,尽快远离那个点每一步都朝树的边缘走去,走到边缘后就不动了,静静等待。所以最长路径取决与a点走多少步,理解这点是整个问题的核心,所以我们只需要dfs两个点,找到两个点到任意点的距离,然后取dis[a] dis[b]的点,然后取这些点的dis[a]的最大值,最后不要忘记乘2,因为dis[a]只是a走过的距离,而题目要求输出ab的总距离

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 200010;

int n, x;
vector<int> edge[maxn];
int dis[2][maxn];

void dfs(int u, int v, int dist, int flag) {
    dis[flag][v] = dist;
    for (auto vv : edge[v])
        if (vv != u)
            dfs(v, vv, dist + 1, flag);
}
int main(void) {
    cin >> n >> x;
    int t1,t2;
    for (int i = 0; i < n - 1; i++) {
        cin >> t1 >> t2;
        edge[t1].push_back(t2);
        edge[t2].push_back(t1);
    }
    dfs(1, 1, 0, 0); //dist尽可能短 
    dfs(x, x, 0, 1); //dist尽可能长

    int mmax = 0;
    for(int i=1;i<=n;i++)
        if(dis[1][i]<dis[0][i])
            mmax=max(mmax,dis[0][i]*2);

    cout<<mmax<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81673637