题意
给你一颗树,开始时每个结点都有一个小球,每一秒钟每个小球都往上滚一层,当两个球在同一个结点的时候会被消去,如果三个五个七个等在同一个结点的化消去后只剩一个。
分析
这对我来说就TM是英语阅读理解哇!赛场上读题读到懵逼啊!
最容易想到的是一个O(N^2)的算法,最深由maxd层,从第一层枚举到maxd层然后进行DFS,来计算每一层的小球最后落下来还剩几个,但是这样肯定会被卡掉。然后就再想一个类似贪心的方法,直接dfs计算每一层的小球数量,如果偶数则全部会被消掉,如果是奇数则会剩一个。这样做为什么可以,因为可以忽略中间的过程,任何一层的小球最后都会到根。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 7 using namespace std; 8 const int maxn=100000+10; 9 vector<int>G[maxn]; 10 int n; 11 int maxd=0; 12 int num[maxn]; 13 void dfs(int u,int dep){ 14 num[dep]++; 15 maxd=max(maxd,dep); 16 if(G[u].size()==0)return ; 17 for(int i=0;i<G[u].size();i++){ 18 int v=G[u][i]; 19 dfs(v,dep+1); 20 } 21 return ; 22 } 23 24 int main(){ 25 scanf("%d",&n); 26 int a; 27 for(int i=2;i<=n;i++){ 28 scanf("%d",&a); 29 G[a].push_back(i); 30 } 31 dfs(1,1); 32 int ans=0; 33 for(int i=1;i<=n;i++){ 34 if(num[i]%2) 35 ans++; 36 } 37 printf("%d ",ans); 38 return 0; 39 }