「LCA」[USACO10HOL]牛的政治Cow Politics

Posted nicoppa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「LCA」[USACO10HOL]牛的政治Cow Politics相关的知识,希望对你有一定的参考价值。

[USACO10HOL]牛的政治Cow Politics

题目链接:[USACO10HOL]牛的政治Cow Politics

题目大意

给你\(n\)个关系,再给你一共有多少个群落,每个关系包含两个内容,在哪个群落以及当前 \(i\) 节点的父亲节点是谁。然后让你求每个群落距离最远的两个点的距离是多大

题目题解

刚开始想的是树的直径,但看了下样例发现都是在一棵树上进行的,搜肯定不怎么好搜,想想其他的办法。然后又想到LCA可以求两点的距离,那么可以考虑用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]);
    

以上是关于「LCA」[USACO10HOL]牛的政治Cow Politics的主要内容,如果未能解决你的问题,请参考以下文章

[USACO06JAN]牛的舞会The Cow Prom

[USACO06JAN]牛的舞会The Cow Prom

P2863 [USACO06JAN]牛的舞会The Cow Prom

[USACO06DEC]牛的野餐Cow Picnic DFS

P2863 [USACO06JAN]牛的舞会The Cow Prom

洛谷P2853 [USACO06DEC]牛的野餐Cow Picnic