[agc008F]Black Radius
大佬的博客讲得很好我就不赘述啦,这里提供链接:https://www.cnblogs.com/yoyoball/p/9483816.html
我就放一波代码
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int INF=100000000; char ch[200010]; int n,x,y;long long ans=0; int _col[200010],all; int col1[200010];//col1为统计以i为根子树可选点个数 int mx1[200010],mx2[200010],maxfa[200010];//maxfa为以i为根的点向上能延伸到的最大值 int _down[200010];//当以点i为根时,半径的下界 struct node{int y,nxt; }g[400010];int h[200010],tot=0; void dfs1(int x,int fa) { if (_col[x]) col1[x]=1,_down[x]=0; else _down[x]=INF; for (int i=h[x];i;i=g[i].nxt) if (g[i].y!=fa) { dfs1(g[i].y,x); int cnt=mx1[g[i].y]+1; if (cnt>mx1[x]) mx2[x]=mx1[x],mx1[x]=cnt; else mx2[x]=max(mx2[x],cnt); if (col1[g[i].y]) col1[x]+=col1[g[i].y],_down[x]=min(_down[x],mx1[g[i].y]+1); } } void dfs2(int x,int fa) { if (all-col1[x]) _down[x]=min(_down[x],maxfa[x]); if (fa) { if (maxfa[x]-1<=mx1[x]&&(all-col1[x])) ans++; else if (maxfa[x]-1>=mx1[x]&&col1[x]) ans++; } for (int i=h[x];i;i=g[i].nxt) if (g[i].y!=fa) { int cnt=(mx1[x]==mx1[g[i].y]+1)?mx2[x]:mx1[x]; maxfa[g[i].y]=max(cnt+1,maxfa[x]+1); dfs2(g[i].y,x); } } int main() { scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d",&x,&y); g[++tot]=node{y,h[x]};h[x]=tot; g[++tot]=node{x,h[y]};h[y]=tot; } scanf("%s",ch+1); all=ans=0; for (int i=1;i<=n;i++) if (ch[i]=='1') _col[i]=1,all++; dfs1(1,0); dfs2(1,0); for (int i=1;i<=n;i++) { if (maxfa[i]>mx1[i]) mx2[i]=mx1[i],mx1[i]=maxfa[i]; else mx2[i]=max(mx2[i],maxfa[i]); if (mx2[i]-_down[i]+1>0) ans+=mx2[i]-_down[i]+1; } cout<<ans; }

浙公网安备 33010602011771号