POJ 2378 Tree Cutting(树形DP,水)
题意:给出一棵树(n个节点),去掉一个点后,每个子树的节点数都不大于 n/2,求出这样的节点并按升序输出
树形dp,很神圣的样子,就是树形dfs嘛。。。
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cmath> #include<algorithm> #define nMAX 10010 using namespace std; int head[nMAX],dp[nMAX]; int s_edge,n,num,ans[nMAX]; struct Edge { int u,v,nxt; }edge[nMAX*2]; void addedge(int u,int v) { s_edge++; edge[s_edge].v=v; edge[s_edge].nxt=head[u]; head[u]=s_edge; } int max(int a,int b) { return a>b?a:b; } int dfs(int u,int father) { int cnt=1,SUM=0; for(int e=head[u];e;e=edge[e].nxt) { int v=edge[e].v; if(v==father)continue; int son=dfs(v,u); SUM=max(son,SUM); cnt+=son; } SUM=max(SUM,n-cnt); if(SUM<=n/2){ans[num++]=u;} return cnt; } int main() { int i,j,k; while(~scanf("%d",&n)) { memset(head,0,sizeof(head)); s_edge=0; for(k=1;k<n;k++) { scanf("%d%d",&i,&j); addedge(i,j); addedge(j,i); } memset(dp,0,sizeof(dp)); num=0; dfs(1,0); if(num==0){printf("NONE\n");continue;} sort(ans,ans+num); for(i=0;i<num;i++) printf("%d\n",ans[i]); } return 0; }