poj 2378 树形 dp
2012-10-18 14:13
183 查看
题目:http://poj.org/problem?id=2378
题意:
给定一棵无向树,节点为n(n<=10000),问删除那些节点可以使得新图中的每一个连通分支的节点数都不超过小于n/2
思路:
树形dp,任意定跟,求出每个节点的儿子节点,每个点为根的子树的节点数dp[i],然后考察每一个点,如果n-dp[i]<=n/2,以及以i的每一个儿子为根的子树的节点数都dp[u]<=n/2,那么这个点就满足条件
代码:
题意:
给定一棵无向树,节点为n(n<=10000),问删除那些节点可以使得新图中的每一个连通分支的节点数都不超过小于n/2
思路:
树形dp,任意定跟,求出每个节点的儿子节点,每个点为根的子树的节点数dp[i],然后考察每一个点,如果n-dp[i]<=n/2,以及以i的每一个儿子为根的子树的节点数都dp[u]<=n/2,那么这个点就满足条件
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<cstring> using namespace std; const int maxn=10002; int dp[maxn],sum[maxn],n,flag; vector<int>p[maxn]; int dfs(int u,int fa) { int i,j,v,sum=1,mson=0; int cnt=p[u].size(); dp[u]=0;//子孩子 for(i=0;i<cnt;i++) { v=p[u][i]; if(v==fa)continue; int ans=dfs(v,u); mson=max(mson,ans);//孩子节点中最大孩子数 sum+=ans;///以u 为根所有孩子数 } dp[u]=max(n-sum,mson);///删除u节点, return sum; } int main() { while(scanf("%d",&n)!=EOF) { int i,j,a,b; flag=0; for(i=1;i<=n;i++)p[i].clear(); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); p[a].push_back(b); p[b].push_back(a); } dfs(1,0); for(i=1;i<=n;i++) { if(2*dp[i]<=n) { flag=1; printf("%d\n",i); } } if(!flag)printf("NONE\n"); } return 0; } /* 10 1 2 2 3 3 4 4 5 6 7 7 8 8 9 9 10 3 8 */
相关文章推荐
- poj 2378 Tree Cutting (树形dp)
- poj 2378 Tree Cutting(树形DP,删点使得独立的部分结点数不超过n/2)
- POJ--2378--Tree Cutting--树形DP
- poj 2378 Tree Cutting(树形dp)
- poj 2378 树形dp求树的割点
- POJ 2378 Tree Cutting【树形DP】
- 树形DP____AllenLSY( POJ 2378 )
- poj 2378 Tree Cutting 树形dp
- poj 2378 Tree Cutting 树形dp (删点)
- poj 2378(树形dp)
- Poj 2378 Tree Cutting (树形DP)
- POJ 2378 树形DP??
- 【POJ】2378 - Tree Cutting 树形dp
- poj 2378 简单树形dp
- POJ 2378 树形DP??
- POJ 2378-Tree Cutting(树形dp)
- POJ - 2378 Tree Cutting(树形dp)
- Tree Cutting - POJ 2378 树形dp
- poj 2378(树形dp)
- poj 2378 Tree Cutting 树形DP