「LCA」[USACO10HOL]牛政治牛の政治

[USACO10HOL]牛政治牛の政治

トピックへのリンク:[USACO10HOL]牛政治牛の政治

効果の対象に

あなた\(N \)各関係は、2つのコンテンツで構成さとの関係は、あなたのコミュニティの数を与えるもので、コミュニティと現在の\(私は\)はいノードの父です。そして、あなたは、各コミュニティの2点間の距離が最も遠いどのくらいです見つけます

問題のトピックソリューション

ただ、木の直径のことを考え始めるが、ツリーに行った見つかったサンプルを見て、検索は、他の方法を考え、確かに非常に良い検索ではありません。その後、あなたは1点として最深点を選択した場合、問題の意味を理解することによってあなたはLCAは、我々が知ることができる2点間の距離を求めて使用することを検討することができ、2点間の距離を見つけることができますLCAを考える、それは他のセットを持っています私たちの答えは(単純貪欲)で、我々は最初の点の位置を決定するプログラムの点から、その後、直接トラバース最大距離を計算して算出していないOKにそれ、それから... AC

コードは以下の通りです

//#define fre yes

#include <cstdio>
#include <cstring>
#include <iostream>

const int N = 200005;
int head[N << 1], to[N << 1], ver[N << 1];
int maxx[N], color[N], ans[N];
int depth[N], f[N][22], lg[N];

int n, m, root;

int tot;
void addedge(int x, int y) {
    ver[tot] = y;
    to[tot] = head[x];
    head[x] = tot++;
}

void dfs(int u, int fa) {
    depth[u] = depth[fa] + 1;
    f[u][0] = fa;
    for (int i = 1; (1 << i) <= depth[u]; i++) {
        f[u][i] = f[f[u][i - 1]][i - 1];
    }
    
    for (int i = head[u]; ~i; i = to[i]) {
        int v = ver[i];
        if(v != fa) {
            dfs(v, u);
        }
    }
}

int LCA(int u, int v) {
    if(depth[u] < depth[v]) {
        std::swap(u, v);
    }
    
    while(depth[u] > depth[v]) {
        u = f[u][lg[depth[u] - depth[v]] - 1];
    } if(u == v) return u;
    
    for (int i = lg[depth[u]] - 1; i >= 0; i--) {
        if(f[u][i] != f[v][i]) {
            u = f[u][i];
            v = f[v][i];
        }
    }
    
    return f[u][0];
}

int Dis(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[LCA(u, v)];
}

int main() {
    memset(head, -1, sizeof(head));
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        int x, u;
        scanf("%d %d", &x, &u);
        color[i] = x;
        addedge(i, u);
        addedge(u, i);
        if(!u) root = i;
    }
    
    dfs(root, -1);
    for (int i = 1; i <= n; i++) {
        lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    }
    
    for (int i = 1; i <= n; i++) {
        if(depth[maxx[color[i]]] < depth[i]) {
            maxx[color[i]] = i;
        }
    }
    
    for (int i = 1; i <= n; i++) {
        ans[color[i]] = std::max(ans[color[i]], Dis(maxx[color[i]], i));
    }
    
    for (int i = 1; i <= m; i++) {
        printf("%d\n", ans[i]);
    }
}

おすすめ

転載: www.cnblogs.com/Nicoppa/p/11516131.html