实现不难,对我这种辣鸡来说有一定的思维量。
对于每个点我们只需要知道它的子树大小的总和和它最大的子树大小是多少就可以了。
因为对于每个点 只要知道了它的子树大小的总和那么也就知道了 它的所有父亲以及兄弟的数量(n-子树大小)
因为对于这个点来说,割去后对答案产生影响的只有它最大的子树大小。
如果割去这个点后 它的所有父亲以及兄弟的数量<=n/2 同时 最大的子树大小也<=n/2
那么一定是可行的。
#include <cstdio> #include <algorithm> using std::max; struct node{ int u,v,next; node(){} node(int _u,int _v,int _next){ u = _u; v = _v; next = _next; } }Edge[20005]; int n,head[20005],Count; int sum[20005],Max[20005]; inline void AddEdge(int u,int v){ Count++; Edge[Count] = node(u,v,head[u]); head[u] = Count; } void dfs(int x,int fa){ sum[x]=1; for(int i=head[x];i;i=Edge[i].next){ int v = Edge[i].v; if(v==fa) continue; dfs(v,x); sum[x]+=sum[v]; } for(int i=head[x];i;i=Edge[i].next){ int v = Edge[i].v; Max[x] = max(Max[x],sum[v]); } } int main(){ scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); AddEdge(u,v); AddEdge(v,u); } dfs(1,-1); int limit = n/2; for(int i=1;i<=n;i++){ if(n-sum[i]<=limit && Max[i] <= limit ) printf("%d\n",i); } return 0; }
时间: 2024-10-06 14:48:07