poj 1655 Balancing Act(树形dp)

来源:互联网 发布:我的世界js制作器教程 编辑:程序博客网 时间:2024/05/21 09:47

求树的重心,如果有多个,输出编号最小的。
在树形dp题单看到了poj 1741 Tree,只会暴力搜索,不会别的办法。就搜题解,发现这是个树分治啊,怎么会在树形dp里?求解过程中涉及到了求树的重心,不会求,百度,才发现原来树形dp在求树的重心这里这里写图片描述
树的直径、树的重心与树的点分治:http://www.cnblogs.com/zinthos/p/3899075.html

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int MAXN = 20010;const int MAXM = 40020;struct Edge{    int to,next;}edge[MAXM];int tot;int head[MAXN];int son[MAXN];int N;int ans1,ans2;void init(){    tot = 0;    memset(son,0,sizeof(son));    memset(head,-1,sizeof(head));}void addedge(int u, int v){    edge[tot].to = v;    edge[tot].next = head[u];    head[u] = tot++;}void dfs(int u, int fa){    son[u] = 1;    int res = 0;    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if(v == fa) continue;        dfs(v,u);        son[u] += son[v];        res = max(res,son[v]);    }    res = max(res,N-son[u]);    if(res < ans2)    {        ans2 = res;        ans1 = u;    }    else if(res == ans2 && u < ans1)        ans1 = u;}int main(){    int T,n,a,b;    scanf("%d",&T);    while(T--)    {        ans2 = MAXN;        init();        scanf("%d",&n);        N = n;        for(int i = 0; i < n-1; ++i)        {            scanf("%d %d",&a,&b);            addedge(a,b);            addedge(b,a);        }        dfs(1,-1);        printf("%d %d\n",ans1,ans2);    }    return 0;}
原创粉丝点击