Codeforces Round #322 (Div. 2) F. Zublicanes and Mumocrates(树形dp)

来源:互联网 发布:vr视频软件 编辑:程序博客网 时间:2024/04/30 15:32

题意:

2N5000,
:
,使

分析:

dp
dp[u][cnt][2]:=u0/1,cnt1
dp
f[u][cnt][2]:=ucnt1,u0/1
leaves[u]:=u
f[u][1][1]=f[u][0][0]=0,leaves[u]=1
,1,u1,v
u,
g[0][cnt][2]:=u,0/1,g[0][0][0]=g[0][0][1]=0
g[1][cnt][2]:=u,u1u
g,u
,f[u]=g[cur]
halfLeaves=leaves[root]/2, ans=min(f[root][halfLeaves][0],f[root][halfLeaves][1])
便
n=2,,ans=1
O(n2),(x,y)lca
这里写图片描述
,O(n3)

代码:

////  Created by TaoSama on 2016-02-02//  Copyright (c) 2015 TaoSama. All rights reserved.//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 5e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;int n;int f[N][N][2], g[2][N][2], leaves[N]; //leaf to 1vector<int> G[N];void getMin(int &x, int y) {    if(x > y) x = y;}void see(int u) {    printf("%d:\n", u);    for(int i = 0; i <= leaves[u]; ++i)        for(int j = 0; j < 2; ++j)            printf("f[%d][%d]=%d\n", i, j, f[u][i][j]);    puts("");}void dfs(int u, int fa) {    leaves[u] = 0;    if(G[u].size() == 1) {        leaves[u] = 1;        f[u][0][0] = f[u][1][1] = 0;        f[u][0][1] = f[u][1][0] = INF;//      see(u);        return;    }    for(int v : G[u]) {        if(v == fa) continue;        dfs(v, u);    }    int p = 0;    g[p][0][0] = g[p][0][1] = 0;    for(int v : G[u]) {        if(v == fa) continue;        memset(g[!p], 0x3f, sizeof g[!p]);        for(int i = 0; i <= leaves[u]; ++i)            for(int j = 0; j <= leaves[v]; ++j)                for(int a = 0; a < 2; ++a)                    for(int b = 0; b < 2; ++b)                        getMin(g[!p][i + j][a], g[p][i][a] + f[v][j][b] + (a != b));        p = !p;        leaves[u] += leaves[v];    }    memcpy(f[u], g[p], sizeof g[p]);//  see(u);}int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif    ios_base::sync_with_stdio(0);    while(scanf("%d", &n) == 1) {        for(int i = 1; i <= n; ++i) G[i].clear();        for(int i = 1; i < n; ++i) {            int u, v; scanf("%d%d", &u, &v);            G[u].push_back(v);            G[v].push_back(u);        }        if(n == 2) {puts("1"); continue;}        for(int i = 1; i <= n; ++i) {            if(G[i].size() > 1) {//              printf("root:%d\n", i);                dfs(i, -1);                int cnt = leaves[i] >> 1;                int ans = min(f[i][cnt][0], f[i][cnt][1]);                printf("%d\n", ans);                break;            }        }    }    return 0;}
0 0
原创粉丝点击