• POJ 3140 Contestants Division


    题目大意:

    n个点,每个点有个权值,m条边,形成一棵树,这道题里面,m就是坑爹的,实际上就是 m = n-1 ,不考虑它也没问题 , 写在这里吓唬人的

    只能建一条通信道 , 也就是找到一条边作为通信通道,然后这个通信通道分割了2棵树,求得到两棵树权值之和相差的值最小

    这里数据比较大,要用到 long long

    开始对于m,n的数据给定完全不理解,看了别人的说这个没用,就好做很多了

    用sum[i]记录 i 对应的树中权值总和

    dfs一次即可,通过sum[i]来解决问题

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int N = 100005;
     8 
     9 int first[N] , k , val[N];
    10 ll sum[N] , all;
    11 
    12 struct Edge{
    13     int y , next , flag;
    14 }e[N<<1];
    15 
    16 ll my_abs(ll x)
    17 {
    18     return x>=0?x:-x;
    19 }
    20 
    21 void add_edge(int x , int y)
    22 {
    23     e[k].y = y , e[k].next = first[x] , e[k].flag = false;
    24     first[x] = k++;
    25 }
    26 
    27 void dfs(int u , int fa)
    28 {
    29     sum[u] = val[u];
    30     for(int i=first[u] ; i!=-1 ; i=e[i].next){
    31         int v = e[i].y;
    32         if(v == fa) continue;
    33         dfs(v , u);
    34         e[i].flag = true;
    35         sum[u]+=sum[v];
    36     }
    37 }
    38 
    39 int main()
    40 {
    41   //  freopen("a.in" , "r" , stdin);
    42     int n , m , x , y , cas=0;
    43     while(scanf("%d%d" , &n , &m) , n||m){
    44         memset(first , -1 , sizeof(first));
    45         k=0 , all = 0;
    46         for(int i=1 ; i<=n ; i++)
    47         {
    48             scanf("%d" , val+i);
    49             all += val[i];
    50         }
    51 
    52         for(int i=0 ; i<m ; i++){
    53             scanf("%d%d" , &x , &y);
    54             add_edge(x , y);
    55             add_edge(y , x);
    56         }
    57 
    58         dfs(1 , -1);
    59         ll ans = 100000000;
    60         ans = ans*ans;
    61       /*  for(int i=1 ; i<=n ; i++)
    62             cout<<"i: "<<i<<" "<<sum[i]<<endl;*/
    63         for(int i=0 ; i<k ; i++){
    64             if(!e[i].flag) continue;
    65             ll t = my_abs(all - sum[e[i].y] - sum[e[i].y]);
    66             ans = min(ans , t);
    67         }
    68         printf("Case %d: %lld
    " , ++cas , ans);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    .net framework缓存遍历
    R语言中统计数据框所有项中的并集
    R语言中在数据框中批量替换指定项
    R语言中 %in%用法
    windows中如何查看端口占用情况、端口是否开启
    R语言中rbind函数和cbind的用法
    linux系统shell实现统计 plink文件基因频率
    linux 系统中实现列转行 及 行转列
    linux系统中向行末添加换行符
    R语言中实现方差和标准差
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4234170.html
Copyright © 2020-2023  润新知