poj1655 2378 3107 树形dp

树形dp的感觉
给你一棵无向树t,要求依次去除树中的某个结点,求去掉该结点后变成的森林t'各分支的最大节点数最小。
sum为节点数,a为其子树的最大节点数

#include <iostream> using namespace std; struct gtype { int x,y,next,op; }g[40005]; int t,n,i,ans,id,x,y,sum[40005],first[20005],a[20005],tot; bool v[20005]; void add(int x,int y) { tot++; g[tot].y=y; g[tot].next=first[x]; first[x]=tot; tot++; g[tot].y=x; g[tot].next=first[y]; first[y]=tot; } void dfs(int x) { v[x]=true; int t; for (t=first[x];t!=-1;t=g[t].next) { if (v[g[t].y]==false) { dfs(g[t].y); sum[x]+=sum[g[t].y]; if (sum[g[t].y]>a[x]) a[x]=sum[g[t].y]; } } } int main() { cin >> t; while (t--) { cin >> n; tot=0; memset(first,-1,sizeof(first)); memset(g,0,sizeof(g)); for (i=1;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); } memset(v,0,sizeof(v)); memset(a,0,sizeof(a)); for (i=1;i<=n;i++) sum[i]=1; dfs(1); ans=a[1]; id=1; for (i=2;i<=n;i++) if (ans>max(a[i],sum[1]-sum[i])) { ans=max(a[i],sum[1]-sum[i]); id=i; } printf("%d %d/n",id,ans); } system("pause"); return 0; }

你可能感兴趣的:(System,ini)