zoukankan      html  css  js  c++  java
  • 2019 年百度之星·程序设计大赛

    题目:https://vjudge.net/contest/325352#problem/A

    题意:给你一棵树,每个点给一个区间,可以选区间里面任何一个数,然后问怎么安排得到最大边两点之间的差值和,求这个最大差值和

    思路:首先可以想到每个点肯定是选择区间端点值,也就是说每个点实际上只有两个值可以选,但是我们安排当前值求出最大边差值不一定最优,这个时候我们可以设立一个数组dp[n][2],代表选当前点的L能得到的最大值和当前选R能得到的最大值,这样最后递归到根节点1就能求出最大值是多少

    #include<bits/stdc++.h>
    #define maxn 100005
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    struct sss{
        ll l,r;
    }a[maxn];
    int t,n; 
    vector<int> mp[maxn];
    ll dp[maxn][2];
    void dfs(int x,int f){
        for(int i=0;i<mp[x].size();i++){
            int v=mp[x][i];
            if(v==f) continue;
            dfs(v,x);
            dp[x][0]+=max(abs(a[x].l-a[v].l)+dp[v][0],abs(a[x].l-a[v].r)+dp[v][1]);//所有子树的差值和
            dp[x][1]+=max(abs(a[x].r-a[v].l)+dp[v][0],abs(a[x].r-a[v].r)+dp[v][1]);
        } 
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                mp[i].clear();
            }
            memset(dp,0,sizeof(dp));
            int x,y;
            for(int i=0;i<n-1;i++){
                scanf("%d%d",&x,&y);
                mp[x].push_back(y);
                mp[y].push_back(x);    
            }    
            for(int i=1;i<=n;i++){
                scanf("%d%d",&a[i].l,&a[i].r);
            }
            dfs(1,-1);
            printf("%lld
    ",max(dp[1][0],dp[1][1])); 
        }
    } 
  • 相关阅读:
    bzoj2957 -- 线段树
    bzoj2209 [ JSOI2011 ] -- splay
    bzoj3874 [ AHOI2014 ] -- 爬山算法
    bzoj1038 [ ZJOI2008 ] -- 模拟退火+二分
    bzoj2428 [ HAOI2006 ] -- 模拟退火
    bzoj3680 -- 模拟退火
    bzoj4500 -- 差分约束
    bzoj3527 -- FFT
    bzoj1013 [ JSOI2008 ] -- 高斯消元
    使用nginx try_files 指令 管理静态资源
  • 原文地址:https://www.cnblogs.com/Lis-/p/11502379.html
Copyright © 2011-2022 走看看