• 【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 }
  • 相关阅读:
    laravel 5.2 引入第三方类
    jquery获得option的值和对option进行操作
    复习知识点
    前端使用crypto.js进行加密
    使用jQuery Pagination Plugin实现分页效果
    配置文件
    MyBatis的适用场景和生命周期
    使用GET方式提交的表单遇到的问题
    Java复习——网络编程
    SpingData 的学习
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/6066184.html
Copyright © 2020-2023  润新知