zoukankan      html  css  js  c++  java
  • POJ 3140 Contestants Division 树形DP

    题意:

    有一棵树,有点权,你可以选择一条边删除,要求删除后形成的2棵子树的权值的差的绝对值最小

    输出这个最小值

    本来是简单题,一个数组siz

    siz[i]表示以i为根的子树的节点的权值之和

    然后遍历一遍,找到最小值即可。

    注意:

    0.点权要long long

    1.由于点权之和是long long 的,你在求最小值的时候,初始化ret,

       要初始化为ret=0x3f3f3f3f3f3f3f3f,而不能是0x3f3f3f3f

    2.输入的数据描述的是n m

      (1 ≤ N ≤ 100000, 1 ≤ M ≤ 1000000)

      n表示节点的个数,m表示边的个数

      然后我就呆了,题目明明说了这是一棵树啊,也就是边数为n-1啊,这里弄个m<= 1000000是什么?

      然后想想才知道,这是唬人的,数据一定会保证m=n-1的,被骗了,然后还以为自己读错题意了,又看了很久的题目

    3.这里的abs()函数要自己写,因为cmath的abs()函数是int abs()的,在这里不适合,会CE

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    
    #define ll long long
    
    using namespace std;
    
    const int maxn=1e5+10;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    
    struct Edge
    {
        int to,next;
    };
    Edge edge[maxn<<1];
    int tot;
    int head[maxn];
    
    ll val[maxn];
    ll siz[maxn];
    ll sum;
    
    void init()
    {
        memset(head,-1,sizeof head);
        tot=0;
        sum=0;
    }
    
    void addedge(int u,int v)
    {
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    
    ll solve(int );
    
    int main()
    {
        int cas=1;
        int n,m;
        while(scanf("%d %d",&n,&m)){
            if(!n&&!m)
                break;
            printf("Case %d: ",cas++);
            init();
            for(int i=1;i<=n;i++){
                scanf("%lld",&val[i]);
                sum+=val[i];
            }
    
            for(int i=1;i<=m;i++){
                int u,v;
                scanf("%d %d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            printf("%lld
    ",solve(n));
        }
        return 0;
    }
    
    void dfs(int u,int pre)
    {
        siz[u]=val[u];
        for(int i=head[u];~i;i=edge[i].next){
            int v=edge[i].to;
            if(v==pre)
                continue;
            dfs(v,u);
            siz[u]+=siz[v];
        }
    }
    
    ll solve(int n)
    {
        //printf("eee
    ");
        dfs(1,-1);
    
        ll ret=inf;
        for(int i=2;i<=n;i++){
            ll cnt=sum-2*siz[i];
            if(cnt<0)
                cnt*=(-1);
            if(cnt<ret)
                ret=cnt;
        }
        return ret;
    }
  • 相关阅读:
    远程登陆服务——SSH
    A web-based 3D modeling framework for a runner-gate design( 一种基于web的三维建模框架)
    Vue+Element+Echarts+Springboot+微信小程序开发(肿瘤医学项目)
    基于拖放布局的 Twitter Bootstrap 网站生成器
    Ubuntu下git使用华为云/gitee/github
    在 Ubuntu 18.04 上安装 Postman
    在Ubuntu 18.04上安装Git与入门教程
    转载:渲染层和逻辑层
    Ubuntu系统中安装Neo4j
    NosqlBooster连接数据库失败connect ECONNREFUSED 127.0.0.1:27017——mongodb连接失败
  • 原文地址:https://www.cnblogs.com/-maybe/p/4825885.html
Copyright © 2011-2022 走看看