您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: