POJ 3107 Godfather (水题,树形DP)

来源:互联网 发布:模拟人生4捏脸帅哥数据 编辑:程序博客网 时间:2024/05/18 01:21

思路:设dp[i]为在i的子树中,删去i后的最大连通子图的顶点个数。

dp[u] = max(dp[u],num[v])。


代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn = 50005;const int INF = 1e6+5;struct Nod{    int b,next;    void init(int b,int next){        this->b=b;this->next=next;    }}buf[maxn<<1];int len,E[maxn];int n,num[maxn],dp[maxn];void init(){    len=0;    memset(E,-1,sizeof(E));    memset(dp,0,sizeof(dp));}void add_edge(int a,int b){    buf[len].init(b,E[a]);E[a]=len++;    buf[len].init(a,E[b]);E[b]=len++;}void dfs(int u,int pre){    int i,v;    num[u] = 1;    for(i=E[u];i!=-1;i=buf[i].next){        v=buf[i].b;        if(v == pre) continue;        dfs(v,u);        num[u] += num[v];        dp[u] = max(dp[u],num[v]);    }    dp[u] = max(dp[u],n-num[u]);}int main(){    int i,j,a,b,o = INF;    init();    scanf("%d",&n);    for(i=1;i<n;i++){        scanf("%d%d",&a,&b);        add_edge(a,b);    }    dfs(1,-1);    for(i=1;i<=n;i++) o = min(o,dp[i]);    for(i=1,j=0;i<=n;i++){        if(o == dp[i]){            if(j) putchar(' ');j++;            printf("%d",i);        }    }    return 0;}


0 0