bzoj3391[Usaco2004 Dec]Tree Cutting网络破坏*
bzoj3391[Usaco2004 Dec]Tree Cutting网络破坏
题意:
给一棵树,问去掉哪个点后可以使剩下的每个子树大小都小于等于节点总数的一半。n≤10000。
题解:
dfs的时候求一下子树大小,以当前节点的父节点为根节点的子树大小为n-以当前节点为根节点的子树大小。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 10010 7 using namespace std; 8 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 13 return f*x; 14 } 15 struct e{int t,n;}es[maxn*2]; int ess,g[maxn]; 16 void pe(int f,int t){ 17 es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess; 18 } 19 int sz[maxn],n,ans[maxn],tot; 20 void dfs(int x,int fa){ 21 int mx=0; sz[x]=1; for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa){ 22 dfs(es[i].t,x); sz[x]+=sz[es[i].t]; mx=max(mx,sz[es[i].t]); 23 } 24 mx=max(mx,n-sz[x]); if(mx<=n/2)ans[++tot]=x; 25 } 26 int main(){ 27 n=read(); inc(i,1,n-1){int x=read(),y=read(); pe(x,y);} dfs(1,0); 28 if(!tot){printf("NONE"); return 0;} 29 sort(ans+1,ans+1+tot); inc(i,1,tot)printf("%d\n",ans[i]); return 0; 30 }
20161114