zoukankan      html  css  js  c++  java
  • 【LCA】BZOJ1776-[Usaco2010 Hol]cowpol 奶牛政坛

    【题目大意】

    一棵n个点的树,树上每个点属于一个党派,要求每个党派的最远距离点。两点间距离为两点间边的个数。

    【思路】

    yy一下可知,最远距离点中必有一个是该党派深度最深的一个,那么我们就记下最深的点,然后枚举跑LCA……O(nlongn)裸的倍增LCA。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=200000+50;
     4 const int DEG=20;
     5 int n,k,rt;
     6 int dep[MAXN],party[MAXN],maxdep[MAXN],maxpos[MAXN],maxdis[MAXN];
     7 vector<int> E[MAXN];
     8 int anc[MAXN][DEG];
     9 
    10 void getanc()
    11 {
    12     for (int i=1;i<DEG;i++)
    13         for (int j=1;j<=n;j++)
    14             anc[j][i]=anc[anc[j][i-1]][i-1];
    15 } 
    16 
    17 int swim(int x,int H)
    18 {
    19     for (int i=0;H>0;i++)
    20     {
    21         if (H&1) x=anc[x][i];
    22         H/=2;
    23     }
    24     return x;
    25 }
    26 
    27 int LCA(int u,int v)
    28 {
    29     if (dep[u]<dep[v]) swap(u,v);
    30     u=swim(u,dep[u]-dep[v]);
    31     if (u==v) return u;//不知道为什么总是忘掉这句话(╯▔皿▔)╯ ★★★★
    32     for (int i=DEG-1;i>=0;i--)
    33     {
    34         if (anc[u][i]!=anc[v][i])
    35         {
    36             u=anc[u][i];
    37             v=anc[v][i];
    38         }
    39     }
    40     return (anc[u][0]);
    41 }
    42 
    43 void dfs(int x,int d)
    44 {
    45     dep[x]=d;
    46     for (int i=0;i<E[x].size();i++)
    47     {
    48         int to=E[x][i];
    49         dfs(to,d+1);
    50     }  
    51 }
    52 
    53 void init()
    54 {
    55     scanf("%d%d",&n,&k);
    56     for (int i=1;i<=n;i++)
    57     {
    58         int p;
    59         scanf("%d%d",&party[i],&p);
    60         if (p!=0) E[p].push_back(i);
    61             else rt=i;
    62         anc[i][0]=p;
    63     }
    64     dfs(rt,0);
    65     for (int i=1;i<=n;i++) 
    66         if (maxdep[party[i]]<dep[i]) 
    67         {
    68             maxdep[party[i]]=dep[i];
    69             maxpos[party[i]]=i;
    70         }
    71 }
    72 
    73 void solve()
    74 {
    75     getanc();
    76     memset(maxdis,0,sizeof(maxdis));
    77     for (int i=1;i<=n;i++)
    78     {
    79         int np=party[i],mp=maxpos[np];
    80         int lca=LCA(i,mp);
    81         int nowdis=-2*dep[lca]+dep[i]+dep[mp];
    82         maxdis[np]=max(maxdis[np],nowdis);
    83     }
    84     for (int i=1;i<=k;i++) printf("%d
    ",maxdis[i]); 
    85 }
    86 
    87 int main()
    88 {
    89     init();
    90     solve();
    91     return 0;
    92 }
  • 相关阅读:
    为何与0xff进行与运算
    智能指针学习笔记
    linux下多线程编程
    redis源码分析之内存布局
    spring
    java
    程序员进修之路
    散列类型(hash)
    字符串类型
    Jmeter使用Websocket插件测试SingalR,外加还有阿里云PTS的Jmeter原生测试爬坑日志。
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/6066184.html
Copyright © 2011-2022 走看看