CodeForces 813C The Tag Game

题目链接:CodeForces 813C The Tag Game

题目大意:
CodeForces 813C The Tag Game

题解:
\(A\)一直沿\(A\)、\(B\)之间的最短路径走,\(B\)则往深度更大的结点走。
所以求出刚开始\(A\)、\(B\)之间的路径,找到此路径上\(B\)能在\(A\)之前到达且深度最大的结点\(C\),则\(ans =( 1到C的距离+C与其子树中深度最大的叶子结点之间的距离)*2\)。

#include <cstring>
#include <iostream>
using namespace std;

int n, x, step, d[200010], path[200010], vis[200010], depth[200010];
int cnt, head[200010];
struct Edge {
    int v, next;
} edge[400010];

void addEdge(int u, int v) {
    edge[++cnt].v = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

int dfs(int u, int fa) {  // 求深度
    int maxn = 0;
    for (int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].v;
        if (v != fa) {
            depth[v] = depth[u] + 1;
            maxn = max(dfs(v, u), maxn);
        }
    }
    return d[u] = maxn + 1;
}

void find_path(int u, int fa, int k) {
    if (step) {
        return;
    }
    path[k] = u;
    if (u == x) {
        step = k;
        return;
    }
    for (int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].v;
        if (v != fa) {
            find_path(v, u, k + 1);
        }
    }
}

int main() {
    while (cin >> n >> x) {
        cnt = 0;
        memset(head, 0, sizeof(head));
        for (int i = 1, u, v; i < n; ++i) {
            cin >> u >> v;
            addEdge(u, v);
            addEdge(v, u);
        }
        int ans = 0;
        memset(d, 0, sizeof(d));
        memset(vis, 0, sizeof(vis));
        step = 0, depth[1] = 1;
        dfs(1, 0);
        find_path(1, 0, 1);
        for (int i = step, j = 1; i && !vis[i]; --i, ++j) {
            vis[j] = 1;
            if (!vis[i]) {
                ans = max(ans, d[path[i]] - 1 + depth[path[i]] - 1);
            }
        }
        cout << ans * 2 << endl;
    }
    return 0;
}
上一篇:spark练习:求得用户每次会话的行为轨迹--解决数据倾斜


下一篇:Split Game翻译