3 条题解
-
0
写一个有点丑陋的做法
首先我们考虑有一个很 的贪心, 已经说过了,不再赘述
然后我们直接考虑怎么做
我们直接设 表示我当前有一红一蓝在 点上
然后我们考虑转移
我们发现我们一定是从我子树下面某一个固定深度的点转移
然后我们只要快速找到这棵子树下面的某一深度的所有点就好了
然后我们可以用 序来做这件事情
然后就秒了
CODE
#include<bits/stdc++.h> using namespace std; bool lf[200005]; vector<int>G[200005]; vector<int>ids[200005]; int dep[200005],dfn[200005],redfn[200005],siz[200005]; int mn[200005]; void dfs(int x){ mn[x]=100000000; siz[x]=1; dfn[x]=++dfn[0]; ids[dep[x]].push_back(dfn[x]); redfn[dfn[0]]=x; if(lf[x])mn[x]=dep[x]; for(int i=0; i<(int)G[x].size(); i++){ int y=G[x][i]; dep[y]=dep[x]+1; dfs(y); mn[x]=min(mn[x],mn[y]); siz[x]+=siz[y]; } } int f[200005]; void dfs2(int x){ if(mn[x]==dep[x]){ // f[x]=1; return; } int be=lower_bound(ids[mn[x]].begin(),ids[mn[x]].end(),dfn[x])-ids[mn[x]].begin(); for(int i=be; i<(int)ids[mn[x]].size(); i++){ int dn=ids[mn[x]][i]; if(dn>dfn[x]+siz[x]-1){break;} dfs2(redfn[dn]); f[x]=max(f[x],f[redfn[dn]]); }f[x]++; } int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); int n,p;scanf("%d",&n); memset(lf,1,sizeof lf); for(int i=2; i<=n; i++){ scanf("%d",&p);G[p].push_back(i); lf[p]=0; }dfs(1),dfs2(1); cout<<f[1]; return 0; }
信息
- ID
- 446
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 16
- 已通过
- 5
- 上传者