codeforces Zublicanes and Mumocrates
2015-09-29 23:57
148 查看
给你一棵树,问你把子节点分成两类的最少去掉的边的数量。 边的两个端点颜色不同必须去掉。
树形背包;
树形背包;
#include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 5011; struct node{ int to,next; }edge[MAXN*2]; int tot,head[MAXN]; void init(){ tot = 0; memset(head, -1, sizeof(head)); } void add_edge(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } int d[MAXN]; int dp[MAXN][MAXN][2]; int dfs(int u, int pre){ dp[u][0][0] = 0; dp[u][0][1] = 0; int flag = 1; int cnt = 0; for(int i=head[u]; ~i; i=edge[i].next){ int v = edge[i].to; if(v == pre) continue; flag = 0; int now = dfs(v, u); cnt += now; for(int k=cnt; k>=0; k--){ int MAX[2] = {INF, INF}; for(int j=0; j<=now; j++){ MAX[0] = min(MAX[0], min(dp[u][k-j][0]+dp[v][j][0], dp[u][k-j][0] + dp[v][j][1]+1)); MAX[1] = min(MAX[1], min(dp[u][k-j][1]+dp[v][j][1], dp[u][k-j][1] + dp[v][j][0]+1)); } for(int j= 0; j< 2; j++) dp[u][k][j] = MAX[j]; } } if(flag){ dp[u][1][1] = 0; dp[u][0][1] = INF; } return cnt + flag; } int n; int main(){ memset(dp, 0x3f3f3f3f, sizeof(dp)); cin>>n; init(); for(int i=1; i<n; i++){ int u,v; scanf("%d %d", &u, &v); add_edge(u, v); add_edge(v, u); d[u] ++, d[v]++; } int root; int m = 0; for(int i=1; i<=n; i++){ if(d[i] > 1) root = i; else m++; } if(n == 2){ cout<<1<<endl; return 0; } dfs(root, -1); cout<<min(dp[root][m/2][1], dp[root][m/2][0])<<endl; return 0; }
相关文章推荐
- 结对代码复审结果
- 笔记09 saveFileDialog
- 博客变更通知 http://blog.csdn.net/ostea
- 读jQuery官方文档:样式
- git rebase
- js scroll nav
- linux centos 网卡错误 Device eth0 does not seem to
- listview的上拉加载更多和下拉刷新
- 史上最强视频网站真实地址解析
- 第一阶段小感悟
- mysql 不乱码五种方法
- 【Foundation-37-1】#import <Foundation/NSIndexSet.h>不可索引集合
- 系统吞吐量(TPS)、用户并发量、性能测试概念和公式
- swift关于UIView设置frame值的extension
- LeetCode "Find the Duplicate Number"
- 芒果TV真实视频地址解析
- 项目里出现的问题05(自定义DEBUG)
- 等比数列二分求和
- Handler,Message,Looper深入系统学习
- 折腾kali linux2.0