• HDOJ树形DP专题之Contestants Division


    题目链接

    题目大意:给定一棵树,每个结点有一个权值,一棵树的权值为所有结点的权值和,现将这棵树分为两棵子树,要使得两子树的权值差最小。

    我的做法是先将无根树化为有根树,然后求每棵子树的权值,最后用一次扫描求结果。需要注意的是结果要用long long型。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #define N 100000
     5 #define MAX(a,b) ((a)>(b)?(a):(b))
     6 #define MIN(a,b) ((a)<(b)?(a):(b))
     7 #define D(a,b) ((a)>(b)?(a)-(b):(b)-(a))
     8 using namespace std;
     9 vector<int> g[N],dep[N];
    10 int n,m,a[N],d[N],p[N],dmax;
    11 long long sum[N],ans;
    12 void make_set()
    13 {
    14   for(int i=0;i<n;i++)  p[i]=i;
    15 }
    16 int find_set(int i)
    17 {
    18   return i==p[i]?p[i]:(p[i]=find_set(p[i]));
    19 }
    20 void dfs(int u,int fa)
    21 {
    22   int i,v,l;
    23   d[u]=(fa==-1?0:d[fa]+1);
    24   dmax=MAX(dmax,d[u]);
    25   dep[d[u]].push_back(u);
    26   l=g[u].size();
    27   for(i=0;i<l;i++)
    28   {
    29     v=g[u][i];
    30     if(v!=fa) dfs(v,p[v]=u);
    31   }
    32 }
    33 void dp()
    34 {
    35   int i,j,l,v;
    36   memset(sum,0,sizeof(sum));
    37   for(i=dmax;i>=0;i--)
    38   {
    39     l=dep[i].size();
    40     for(j=0;j<l;j++)
    41     {
    42       v=dep[i][j];
    43       sum[v]+=a[v];
    44       if(i>0) sum[p[v]]+=sum[v];
    45     }
    46   }
    47 }
    48 int main()
    49 {
    50   int i,u,v,kase=0;
    51   while(scanf("%d%d",&n,&m)&&n)
    52   {
    53     for(i=0;i<n;i++)  scanf("%d",&a[i]);
    54     for(i=0;i<n;i++)  g[i].clear();
    55     make_set();
    56     for(i=0;i<m;i++)
    57     {
    58       scanf("%d%d",&u,&v);
    59       u--,v--;
    60       if(find_set(u)==find_set(v))  continue;
    61       p[v]=u;
    62       g[u].push_back(v);
    63       g[v].push_back(u);
    64     }
    65     for(i=0;i<n;i++)  dep[i].clear();
    66     dmax=0;
    67     dfs(0,-1);
    68     dp();
    69     ans=sum[0];
    70     for(i=1;i<n;i++)  ans=MIN(ans,D(sum[i],sum[0]-sum[i]));
    71     printf("Case %d: %lld\n",++kase,ans);
    72   }
    73   return 0;
    74 }
  • 相关阅读:
    Python画图代码
    关于meshgrid和numpy.c_以及numpy.r_
    Reshape以及向量机分类学习和等高线绘制代码
    Python中的数组和list
    关于透视图和等高线
    Iris花逻辑回归与实现
    Crowd安装和破解
    Confluence搭建
    基于搜狗微信搜索获取公众号文章的阅读量及点赞量
    PHP中使用cURL实现Get和Post请求的方法
  • 原文地址:https://www.cnblogs.com/algorithms/p/2474293.html
Copyright © 2020-2023  润新知