zoukankan      html  css  js  c++  java
  • POJ 3140 Contestants Division (树形DP,简单)

    题意:

      有n个城市,构成一棵树,每个城市有v个人,要求断开树上的一条边,使得两个连通分量中的人数之差最小。问差的绝对值。(注意本题的M是没有用的,因为所给的必定是一棵树,边数M必定是n-1)

    思路:

      考虑当前节点t,当断开t与父亲的边时,“子树t中的人数”与“剩下的人数”之差的绝对值若最小,则为答案。

     1 //#include <bits/stdc++.h>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <map>
     7 #include <deque>
     8 #include <algorithm>
     9 #include <vector>
    10 #include <iostream>
    11 #define pii pair<int,int>
    12 #define max(x,y) ((x)>(y)?(x):(y))
    13 #define min(x,y) ((x)<(y)?(x):(y))
    14 #define abs(x) ((x)<0?-(x):(x))
    15 #define INF 2147483647
    16 #define LL  long long
    17 using namespace std;
    18 const double PI  = acos(-1.0);
    19 const int N=1000010;
    20 int edge_cnt, head[N], w[N];
    21 LL ans, sum;
    22 struct node
    23 {
    24     int from, to, next;
    25     node(){};
    26     node(int from,int to,int next):from(from),to(to),next(next){};
    27 }edge[N*2];
    28 
    29 void add_node(int from,int to)
    30 {
    31     edge[edge_cnt]=node(from,to,head[from]);
    32     head[from]=edge_cnt++;
    33 }
    34 
    35 LL DFS(int t,int far)  //枚举删除t头上的边
    36 {
    37     node e;
    38     LL cnt=0;
    39     for(int i=head[t]; i!=-1; i=e.next)
    40     {
    41         e=edge[i];
    42         if(e.to==far)   continue;
    43         cnt+=DFS(e.to, t);
    44     }
    45     cnt+=w[t];  //本子树的人数
    46     ans=min(ans, abs( 2*cnt-sum ));
    47     return cnt;
    48 }
    49 
    50 
    51 int main()
    52 {
    53     //freopen("input.txt", "r", stdin);
    54     int a, b, n, m, Case=0;
    55     while(scanf("%d%d",&n,&m), n+m)
    56     {
    57         sum=edge_cnt=0;
    58         memset(head,-1,sizeof(head));
    59 
    60         for(int i=1; i<=n; i++)
    61         {
    62             scanf("%d",&w[i]);
    63             sum+=w[i];
    64         }
    65         ans=sum;
    66         for(int i=0; i<m; i++)
    67         {
    68             scanf("%d%d",&a,&b);
    69             add_node(a,b);
    70             add_node(b,a);
    71         }
    72         DFS(1,-1);
    73         printf("Case %d: %lld
    ", ++Case, ans);
    74     }
    75     return 0;
    76 }
    AC代码
  • 相关阅读:
    ValidateInput(false)与this.ValidateRequest = false无效的解决方案
    WPF ListView CellTemplate Border设置ListView单元格的边框
    MFC4简单的窗口重绘(非部分重绘)
    针对每个用户的作业(针对用户的定期事件)
    用JQUERY做大表单(多表单域)AJAX提交
    MFC2消息处理
    asp.net mvc实战学习笔记(1)
    NHibernate基础拾遗
    FLEX/FLASH冒泡事件与非冒泡事件
    MFC1创建窗体
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4837659.html
Copyright © 2011-2022 走看看