[Trees differential] [lca] Luogu P3258 squirrel home

Title Description

The new home is a tree squirrel, renovated just a few days ago a new home, a new home there are n rooms, and there are n-1 twig connection, each room can reach each other, and the route between the two rooms is unique of. God, he actually really live in the "tree."

Squirrels like to invite to visit Winnie the Pooh, and also specify a visitor guide, he hopes to be able to follow his guidelines Pooh order, go a1, go to a2, ......, and finally to an, to visit the new home. But this will cause a lot of room to go repeat the Pooh, Pooh lazy constantly decline. But the squirrel told him that each went to a room, he can take a piece of candy to eat from the room.

Pooh is a greedy guy, immediately agreed. Now squirrel want to know in order to ensure the Pooh candy to eat, he needs to put on at least the number of candy in every room.

Since the last room on the squirrel Visitor Guide is an restaurant where he prepared a sumptuous feast, so when the time finally arrives at Pooh restaurant does not need to visit a chance to eat candy.

 

answer

  • Is a relatively bare trees differential topics

 

Code

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #define N 300010
 5 using namespace std;
 6 struct edge{ int to,from,v; }e[N*2];
 7 int n,cnt,head[N],f[40][N],deep[N],a[N],cf[N],vis[N];
 8 void insert(int x,int y)
 9 {
10     e[++cnt].to=y,e[cnt].from=head[x],head[x]=cnt;
11     e[++cnt].to=x,e[cnt].from=head[y],head[y]=cnt;
12 }
13 int lca(int x,int y)
14 {
15     if (deep[x]<deep[y]) swap(x,y);
16     for (int i=30;i>=0;i--) if (deep[f[i][x]]>=deep[y]) x=f[i][x];
17     if (x==y) return x;
18     for (int i=30;i>=0;i--) if (f[i][x]!=f[i][y]) x=f[i][x],y=f[i][y];
19     return f[0][x];
20 }
21 void dfs(int x,int fa)
22 {
23     f[0][x]=fa,deep[x]=deep[fa]+1;
24     for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) dfs(e[i].to,x);
25 }
26 int dfs1(int x)
27 {
28     int ans=cf[x]; vis[x]=1;
29     for (int i=head[x];i;i=e[i].from) if (!vis[e[i].to]) ans+=(e[i].v=dfs1(e[i].to));
30     for (int i=head[x];i;i=e[i].from) if (e[i].to==f[0][x]) e[i].v=ans,i=0;
31     return ans;
32 }
33 int main()
34 {
35     scanf("%d",&n);
36     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
37     for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y);
38     dfs(a[1],a[1]);
39     for (int i=1;(1<<i)<=n;i++) for (int j=1;j<=n;j++) f[i][j]=f[i-1][f[i-1][j]];
40     for (int i=1;i<n;i++)  cf[a[i]]++,cf[a[i+1]]++,cf[lca(a[i],a[i+1])]-=2;
41     memset(vis,0,sizeof(vis)),dfs1(a[1]);
42     for (int i=1;i<=n;i++)
43     {
44         int ans=0;
45         for (int j=head[i];j;j=e[j].from) ans+=e[j].v;
46         if (i==a[n]) ans--; printf("%d\n",(ans+1)/2);
47     }
48 }

 

Guess you like

Origin www.cnblogs.com/Comfortable/p/11333974.html