首页 > 代码库 > 【LCA】BZOJ1776-[Usaco2010 Hol]cowpol 奶牛政坛

【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\n",maxdis[i]); 
85 }
86 
87 int main()
88 {
89     init();
90     solve();
91     return 0;
92 }

 

【LCA】BZOJ1776-[Usaco2010 Hol]cowpol 奶牛政坛