poj 2378 树型dp

和poj1655那道求树的重心基本上一样的,代码也没多大改动。

详情请见

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define MAXN 100000
int N;
vector<int> node[20005];
int num[MAXN];      //num[i]为以i结点为根的树的所有结点数。
int dp[MAXN];
bool vis[MAXN]; //由于为无向图,所以用这个来标记此结点是否计算过。

int dfs(int id)
{
    int n=node[id].size();
    vis[id]=1;
    num[id]=1;
    for(int i=0;i<n;i++)
    {
        if(!vis[node[id][i]])
        num[id]+=dfs(node[id][i]);
    }
    return num[id];
}
void cal(int id)
{
    int n=node[id].size();
    int k;
    vis[id]=1;
    for(int i=0;i<n;i++)
    {
        k=node[id][i];
        if(vis[k])
        {
            dp[id]=max(dp[id],N-num[id]);
        }
        else
        {
            dp[id]=max(dp[id],num[k]);
            cal(k);
        }
    }
}

int main()
{
    int a,b;
    while(scanf("%d",&N)!=EOF)
    {
        for(int i=1;i<=N;i++)
            node[i].clear();
        memset(dp,0,sizeof(dp));
        for(int i=1;i<N;i++)
        {
            scanf("%d%d",&a,&b);
            node[a].push_back(b);
            node[b].push_back(a);
        }
        memset(vis,0,sizeof(vis));
        dfs(1);
        memset(vis,0,sizeof(vis));
        cal(1);
        for(int i=1;i<=N;i++)
        {
            if(dp[i]<=N/2)
            printf("%d\n",i);
        }
    }
    return 0;
}


你可能感兴趣的:(poj 2378 树型dp)