poj 2378 Tree Cutting(树形DP,删点使得独立的部分结点数不超过n/2)
2014-01-22 20:33
489 查看
1、http://poj.org/problem?id=2378
2、题目大意:
一棵树有n个结点,现在要删除某个结点,使得分成的部分结点数最多不超过n/2个,题目与poj 3107类似,只是求得问题不同
用一个cnt[]数组记录下每个点有多少个子节点
那么我们要求的删除根节点u后剩余部分的最大数就是要么是u的子树中的最大值,要么是除去以u为根的树外的剩余结点数dp[u]=max(max(cnt[v]),n-cnt[u]);
3、AC代码:
2、题目大意:
一棵树有n个结点,现在要删除某个结点,使得分成的部分结点数最多不超过n/2个,题目与poj 3107类似,只是求得问题不同
用一个cnt[]数组记录下每个点有多少个子节点
那么我们要求的删除根节点u后剩余部分的最大数就是要么是u的子树中的最大值,要么是除去以u为根的树外的剩余结点数dp[u]=max(max(cnt[v]),n-cnt[u]);
3、AC代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 20005 #define INF 20010 int v ,next ,head ; int tot,ans,res,n; int cnt ; int dp ; void add_edge(int a,int b) { v[tot]=b; next[tot]=head[a]; head[a]=tot++; } void dfs(int u,int fa) { cnt[u]=1; for(int i=head[u];i!=-1;i=next[i]) { int vv=v[i]; if(vv!=fa) { dfs(vv,u); cnt[u]+=cnt[vv]; ans=max(ans,cnt[vv]); } } dp[u]=max(ans,n-cnt[u]); res=min(res,dp[u]); } int main() { int a,b; scanf("%d",&n); memset(head,-1,sizeof(head)); memset(cnt,0,sizeof(cnt)); tot=0; for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); add_edge(a,b); add_edge(b,a); } ans=-INF; res=INF; dfs(1,0); if(res>n/2) printf("NONE\n"); else { for(int i=1;i<=n;i++) { if(dp[i]<=n/2) printf("%d\n",i); } } return 0; }
相关文章推荐
- poj 3107 Godfather(树形DP,点的个数较多, 删点使得剩余部分结点最多的最小值)
- 【POJ】2378 - Tree Cutting 树形dp
- POJ 2378 Tree Cutting【树形DP】
- POJ 2378 Tree Cutting(树形DP)
- poj 2378 Tree Cutting 树形dp
- Poj 2378 Tree Cutting(树形dp)
- POJ 2378-Tree Cutting(树形dp)
- Tree Cutting - POJ 2378 树形dp
- POJ - 2378 Tree Cutting(树形dp)
- poj 2378 Tree Cutting(树形dp)
- POJ 2378 Tree Cutting——树形dp
- POJ--2378--Tree Cutting--树形DP
- poj 2378 Tree Cutting (树形dp)
- Poj 2378 Tree Cutting (树形DP)
- poj 2378 Tree Cutting 树形DP
- poj 2378 Tree Cutting 树形dp (删点)
- poj 2378(树形dp)
- poj 2378 树形 dp
- poj 3342 树形dp_最大独立集合
- POJ 2378 树形DP??