poj1655Balancing Act 树的重心,树形dp

来源:互联网 发布:mac克隆地址是什么意思 编辑:程序博客网 时间:2024/06/07 11:18


poj1655

第一次dfs求出每个子树的节点数

第二次dfs求答案

这一题是poj1741的基础(1741代码)

poj3107也是相同的意思 不过所有点都要输出,并且无法使用stl(数据规模较大)题解

#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;int N;vector<int>son[20010];   //图的存储结构int vis[20010];    //标记是否访问过int num[20010];    //子树节点的数量int dp[20010];    //答案void dfs_num(int n){int len=son[n].size();num[n]=1;vis[n]=1;for(int i=0;i<len;i++){int k=son[n][i];//儿子 if(vis[k])continue;dfs_num(k);num[n]+=num[k];}//printf("@    %d %d\n",n,num[n]);}void dfs_node(int n,int from){int k,len=son[n].size();vis[n]=1;dp[n]=0;for(int i=0;i<len;i++){k=son[n][i];if(vis[k]){dp[n]=max(dp[n],N-num[n]);}else{dp[n]=max(dp[n],num[k]);dfs_node(k,n);}}}int main(){int i,j,k,T,u,v;scanf("%d",&T);while(T--){scanf("%d",&N);for(i=1;i<=N;i++)son[i].clear();memset(num,0,sizeof(num));memset(dp,0,sizeof(dp));for(i=1;i<=N-1;i++){scanf("%d%d",&u,&v);son[u].push_back(v);son[v].push_back(u);}memset(vis,0,sizeof(vis));dfs_num(1);memset(vis,0,sizeof(vis));dfs_node(1,-1);for(i=j=k=N;i>=1;i--){if(k>dp[i]){k=dp[i];j=i;}if(k==dp[i]){j=i;}}printf("%d %d\n",j,k);}return 0;}/*272 61 21 44 53 73 1111 21 31 42 52 64 74 84 98 108 11*/


原创粉丝点击