poj 1655 树形dp

来源:互联网 发布:sql select 结果 左链 编辑:程序博客网 时间:2024/05/17 08:20

题意相当于给你一棵树   让你求每个点的不同子树上的节点个数吧   注意存边的时候存双向边


#include<stdio.h>#include<string.h>#include<iostream>using namespace std;struct node{int to,next;}A[40010];int tot,list[20010],mark[20010],n;int add(int a,int b){A[++tot].to = b;               A[tot].next = list[a];    list[a] = tot;  return 0; }int dp[20010],subtree[20010];int max(int a,int b){return a>b?a:b;}int dfs(int point){mark[point]=1;int b;int k=list[point];if(k==-1) {dp[point]=n-1;subtree[point]=0;return 0;}for(;k!=-1;k = A[k].next)    {   b = A[k].to;   if(mark[b]) continue;   dfs(b);   subtree[point]+=subtree[b]+1;   dp[point]=max(dp[point],subtree[b]+1);   }   dp[point]=max(dp[point],n-subtree[point]-1);   return 0;}int main(){int i,j,T;scanf("%d",&T);while(T--){scanf("%d",&n);tot=1;memset(list,-1,sizeof(list));memset(mark,0,sizeof(mark));for(i=1;i<n;i++){int a,b;scanf("%d%d",&a,&b);add(a,b);add(b,a);}memset(dp,0,sizeof(dp));memset(subtree,0,sizeof(subtree));memset(mark,0,sizeof(mark));dfs(1);int Min=3000000,k;for(i=1;i<=n;i++)if(dp[i]<Min){Min=dp[i];k=i;}printf("%d %d\n",k,Min);}return 0;}

0 0