• HDOJ树形DP专题之Balancing Act


    题目链接

    题目大意:给定一棵树,树的每个结点有一个权值,每个结点的权值=去掉该结点后剩余的分支中结点最多的那个分支的结点数。求树中权值最小的结点。

    这题CE了两次,第一次因为使用了memset没包含头文件,第二次是因为GNU C++没有头文件<memory.h>,使用<string.h>就AC了。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #define N 20000
     5 #define MAX(a,b) ((a)>(b)?(a):(b))
     6 using namespace std;
     7 vector<int> g[N];
     8 int n,p[N],d[N],sum[N],w[N],dmax;
     9 void dfs(int u,int fa)
    10 {
    11   int i,v;
    12   d[u]=(fa==-1?0:d[fa]+1);
    13   dmax=MAX(dmax,d[u]);
    14   for(i=0;i<g[u].size();i++)
    15   {
    16     v=g[u][i];
    17     if(v!=fa) dfs(v,p[v]=u);
    18   }
    19 }
    20 void dp()
    21 {
    22   int i,j;
    23   memset(w,0,sizeof(w));
    24   for(i=0;i<n;i++)  sum[i]=1;
    25   for(i=dmax;i>=0;i--)
    26   {
    27     for(j=0;j<n;j++)
    28     {
    29       if(d[j]!=i) continue;
    30       w[j]=MAX(w[j],n-sum[j]);
    31       if(i>0) w[p[j]]=MAX(w[p[j]],sum[j]),sum[p[j]]+=sum[j];
    32     }
    33   }
    34 }
    35 int main()
    36 {
    37   int i,t,u,v,min;
    38   scanf("%d",&t);
    39   while(t--)
    40   {
    41     scanf("%d",&n);
    42     for(i=0;i<n;i++)  g[i].clear();
    43     for(i=0;i<n-1;i++)
    44     {
    45       scanf("%d%d",&u,&v);
    46       u--,v--;
    47       g[u].push_back(v);
    48       g[v].push_back(u);
    49     }
    50     dmax=0;
    51     dfs(0,-1);
    52     dp();
    53     min=0x7fffffff;
    54     for(i=0;i<n;i++)  if(w[i]<min)  min=w[u=i];
    55     printf("%d %d\n",u+1,min);
    56   }
    57   return 0;
    58 } 
  • 相关阅读:
    如何提高PHP执行效率
    PHP MySQL 预处理语句
    CDN拾遗
    Rendering React components to the document body
    模拟select,隐藏下拉列表的几种实现
    前端数据范式化
    其实我们可以少写点if else和switch
    [译]the cost of javascript in 2018(1)
    provisional headers are shown 知多少
    f5到底刷新了点什么,你知道吗
  • 原文地址:https://www.cnblogs.com/algorithms/p/2473592.html
Copyright © 2020-2023  润新知