POJ 1655 Balancing Act(简单树状DP)

来源:互联网 发布:淘宝刷好评兼职怎么找 编辑:程序博客网 时间:2024/06/14 00:27

题目大意:

给出N个点,N-1条边,删除一个点后分成至少两棵子树,子树中点最多的那棵就称说它Balance

输出:Balance最小的点,和删除该点后的Balance值

思路:

树形DP

用presum来记录该点前的总点数目

然后用sum来记录包括目前点的总的点数

那么连在同一点的其他子树的点数目就为n-sum-1

然后可得dp[u]={presum,n-sum-1};

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<vector>using namespace std;#define min(a,b) a<b?a:b#define max(a,b) a>b?a:b#define N 20020#define INF 0x7FFFFFFvector<int>g[N];int n;int dp[N];int dfs(int u,int pre){int i,sum,t,as;sum = 0;//总点数as = 0;for(i=0;i<g[u].size();i++){int v=g[u][i];if(v==pre)continue;t = dfs(v,u);sum += t;as = max(as,t);}dp[u]=max(n-sum-1,as);return sum+1;}int main(){int T;int i,j,u,v,node,len;scanf("%d",&T);while(T--){scanf("%d",&n);for(i=0;i<=n;i++)g[i].clear();for(i=1;i<n;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}dfs(1,-1);len=dp[1],node=1;for(i=2;i<=n;i++){if(dp[i] < len){len = dp[i];node = i;}}printf("%d %d\n",node,len);}return 0;}