zoukankan      html  css  js  c++  java
  • codeforces 743D

    题意

    给一颗树取出两个不相互包含的子树使权值和最大


    当然是选择DP辣~很容易想到枚举以每一个点为根的子树 找到对于这棵子树来说,之外的权值和最大的子树。第一遍dfs可以找出每个点的子树大小以及以每个点为根 所有子树的最大子树,以及这个子树所在的这个点的儿子节点,以及其他个儿子节点找一颗第二大子树。

    所以对于每一个树来说,与它对应的最大的  另一棵最大权值子树    在父亲节点对应的最大权值子树    以及    父亲节点的另外孩子包含的最大子树上(感觉有点绕==

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #define F    first  
    #define S     second
    #define mem(a,b)    memset(a,b,sizeof(a))
    using namespace std;
    #define INF        0x7ffffffffffffff
    typedef long long int LL;
    #define MAX_N        200005
    LL w[MAX_N];
    struct no
    {
        int v,nexr;    
    }ed[MAX_N*3];
    int stu[MAX_N];
    int col = 0;
    void add(int u , int v){
        ed[col].v = v;
        ed[col].nexr = stu[u];
        stu[u] = col++;
    }
    pair<LL,pair<LL,LL> > ans[MAX_N];
    bool flag[MAX_N];
    int set[MAX_N];
    int cnt[MAX_N];
    void dfs(int u){
        flag[u] = true;
        ans[u].F = w[u];
        for (int i = stu[u]; i != -1  ; i = ed[i].nexr)
        {
            int v = ed[i].v;
            if(flag[v])
                continue;
            dfs(v);
            ans[u].F+=ans[v].F;
            if(ans[v].S.F>ans[u].S.F||ans[v].F>ans[u].S.F){
                set[u]  = v;
                ans[u].S.S = ans[u].S.F;
                ans[u].S.F = max(ans[v].S.F, ans[v].F);
            }
            else if(ans[v].S.F>ans[u].S.S||ans[v].F>ans[u].S.S){
                ans[u].S.S = max(ans[v].S.F,ans[v].F);
            }
        }
    }
    LL res[MAX_N];
    void dfs2(int u){
        flag[u] = true;
        for (int i = stu[u]; i != -1  ; i = ed[i].nexr)
        {
            int v = ed[i].v;
            if(flag[v])
                continue;
            if(set[u] != v)
                res[v] = max (ans[u].S.F,res[u]);
            else 
                res[v] = max (ans[u].S.S,res[u]);
            dfs2(v);
        }
    }
    
    int main(int argc, char const *argv[])
    {
        int n;
        mem(stu,-1);
        scanf("%d",&n);
        for (int i = 1; i <= n ; ++i){
            scanf("%I64d",&w[i]);
            ans[i].F = ans[i].S.F = ans[i].S.S = res[i] = -INF;
        }
        int u , v;
        for (int i = 1; i <= n-1 ; ++i)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
            cnt[u]++;
            cnt[v]++;
        }
        dfs(1);
        mem(flag,false);
        dfs2(1);
        LL pri = -INF;
        for (int i = 1; i <= n ; ++i)
        {
            if(res[i]!=-INF){
                pri = max(res[i]+ans[i].F,pri);
            }
        }
        if(pri==-INF)
            printf("Impossible
    ");
        else
            printf("%I64d
    ",pri );
        return 0;
    }
  • 相关阅读:
    c++中重载、重写、覆盖的区别
    c++值传递,指针传递,引用传递以及指针与引用的区别
    c/c++中static与extern关键字介绍
    Typedef和#define之间的区别
    c++中sizeof()的用法介绍
    c++笔试题:不使用第三个变量来交换俩个变量的数值
    c++位运算符介绍
    3.高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建
    2.高并发教程-基础篇-之nginx+mysql实现负载均衡和读写分离
    1.高并发教程-基础篇-之nginx负载均衡的搭建
  • 原文地址:https://www.cnblogs.com/miamiao/p/6954047.html
Copyright © 2011-2022 走看看