POJ2378->树形DP

来源:互联网 发布:什么是淘宝登录密码 编辑:程序博客网 时间:2024/06/06 15:49
//树形DP
//去掉哪些点可以使树上联通的节点个数小于n/2
//对树进行后序遍历
//状态转移方程:dp[root] = max(n-sum , mason) ;
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>
using namespace std ;
#define MAX 10005
vector<int> tree[MAX] ;
int n;
int dp[MAX] ;


int DFS(int root ,int fa)//root为当前节点, fa 代表该节点的父亲节点
{
    int k ,mason=0;
    int sum = 1;
    int len = tree[root].size() ;
    dp[root] = 0 ;
    for(int i = 0 ; i < len ; i ++)
    {
        k = tree[root][i] ;
        if(k == fa) continue ;
        int ans = DFS(k , root) ;
        mason = max(mason , ans) ;
        sum += ans ;
    }
    dp[root] = max(n-sum , mason) ;
    return sum ;
}
int main()
{
    while(scanf("%d", &n)!= EOF)
    {
        int a , b ;
        for(int i = 1 ; i <= n ; i ++) tree[i].clear();
        for(int i = 1 ; i < n ; i ++)
        {
            scanf("%d%d",&a , &b) ;
            tree[a].push_back(b) ;
            tree[b].push_back(a) ;
        }
        DFS(1,0 ) ;
        int flag = 0 ;
        for(int i = 1 ; i <= n ; i++)
        {
            if(2*dp[i] <= n)
            {
                flag = 1 ;
                cout << i << endl ;
            }
        }
        if(! flag) printf("NONE\n") ;
    }
    return 0 ;
}
0 0
原创粉丝点击