poj 1655 Balancing Act 树状dp

来源:互联网 发布:苹果数据精灵 编辑:程序博客网 时间:2024/05/21 06:15
//poj1655树状dp//求一个数的重心// dfs找到节点v的各个子树的节点数// 取最大值设为num[v],而v节点以上的子树的节点数// 为总数-num[v]-1(包括v节点本身)设为t// dp[v] = max (num[v],t);// 则最终的结果为min(dp[i])对应的i和dp[i];// 对于dp渣渣的我,真的不简单,哎,继续练喽#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 20080;struct Edge{int v;int next;}edges[maxn<<1];bool vis[maxn];int adj[maxn];int dp[maxn];int nu[maxn];int n;int num;void addEdge(int u,int v){edges[num].v = v;edges[num].next = adj[u];adj[u] = num++;edges[num].v = u;edges[num].next = adj[v];adj[v] = num++;}void init(){scanf("%d",&n);num=0;memset(adj,-1,sizeof(adj));memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));memset(nu,0,sizeof(nu));for (int i=0;i<n-1;i++){int a,b;scanf("%d%d",&a,&b);addEdge(a,b);}}int dfs(int u){int sum=0,ans=0;vis[u] = true;for (int i=adj[u];i!=-1;i = edges[i].next){int v = edges[i].v;if (!vis[v]){int t = dfs(v);sum +=t;ans = max (ans,t);}}nu[u] = sum+1;int t = n-nu[u];dp[u]=max(t,ans);return nu[u];}void solve(int &ans,int &index){dfs(1);for (int i=1;i<=n;i++)if (ans>dp[i]){ans=dp[i];index=i;}printf("%d %d\n",index,ans);}// void print(int &ans){// }int main(){int t;freopen("G:\\Code\\1.txt","r",stdin);scanf("%d",&t);while(t--){//printf("111\n");int ans=0x7f7f7f7f;int index=0;init();solve(ans,index);//print(ans);}}

0 0