【USACO】 奶牛政坛

【题目链接】

          点击打开链接

【算法】

         tarjan算法求LCA

【代码】

      

#include<bits/stdc++.h>
#define MAXN 200010
#pragma GOC optimize("O2")

using namespace std;

int n,k,i,p,fa,q;
int a[MAXN],visit[MAXN],parent[MAXN],maxn[MAXN],
    depth[MAXN],x[MAXN],y[MAXN],z[MAXN],ans[MAXN];
vector<int> son[MAXN],vec[MAXN];

int find(int x) {
    if (parent[x] == x) return x;
    parent[x] = find(parent[x]);
    return parent[x];    
} 

void dfs(int dep,int d) {
    int i;
    depth[dep] = d;
    for (i = 0; i < son[dep].size(); i++) 
        dfs(son[dep][i],d+1);
}

void tarjan(int u) {
    int i;
    parent[u] = u;
    visit[u] = 1;
    for (i = 0; i < vec[u].size(); i++) {
        if (y[vec[u][i]] == u && visit[x[vec[u][i]]]) z[vec[u][i]] = find(x[vec[u][i]]);
        if (x[vec[u][i]] == u && visit[y[vec[u][i]]]) z[vec[u][i]] = find(y[vec[u][i]]);
    }
    for (i = 0; i < son[u].size(); i++) {
        if (!visit[son[u][i]]) {
            tarjan(son[u][i]);
            parent[son[u][i]] = u;
        }
    }
}

int main() {
    
    scanf("%d%d",&n,&k);
    for (i = 1; i <= n; i++) {
        scanf("%d%d",&a[i],&p);
        if (p != 0) son[p].push_back(i);
        else fa = i;    
    }
    
    dfs(fa,0);
    
    for (i = 1; i <= n; i++) {
        if (depth[i] > depth[maxn[a[i]]]) 
            maxn[a[i]] = i;    
    }
    
    for (i = 1; i <= n; i++) {
        if (maxn[a[i]] != i) {
            ++q;
            x[q] = maxn[a[i]];
            y[q] = i;
            vec[maxn[a[i]]].push_back(q);
            vec[i].push_back(q);
        }        
    }
    
    tarjan(fa);

    for (i = 1; i <= q; i++) {
        ans[a[x[i]]] = max(ans[a[x[i]]],depth[x[i]] + depth[y[i]] - 2 * depth[z[i]]);
    } 
    for (i = 1; i <= k; i++) printf("%d\n",ans[i]);
    
    return 0;
    
}

 

posted @ 2018-02-14 15:05  evenbao  阅读(233)  评论(0编辑  收藏  举报