zoukankan      html  css  js  c++  java
  • 51NOD 1424 零树(树形DP)

    基准时间限制:1 秒 空间限制:131072 KB

    有一棵以1为根的树,他有n个结点,用1到n编号。第i号点有一个值vi。

    现在可以对树进行如下操作:

    步骤1:在树中选一个连通块,这个连通块必须包含1这个结点。

    步骤2:然后对这个连通块中所有结点的值加1或者减1。

    问最少要经过几次操作才能把树中所有结点都变成0。

    注意:步骤1与步骤2合在一起为一次操作。

    Input
    单组测试数据。
    第一行有一个整数n(1 ≤ n ≤ 10^5)
    接下来n-1行,每行给出 ai 和 bi (1 ≤ ai, bi ≤ n; ai ≠ bi),表示ai和bi之间有一条边,输入保证是一棵树。
    最后一行有n个以空格分开的整数,表示n个结点的值v1, v2, ..., vn (|vi| ≤ 10^9)。
    Output
    输出一个整数表示最少的操作步数。.
    Input示例
    3
    1 2
    1 3
    1 -1 1
    Output示例
    3

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 100005;
    
    long long dp[MAXN][2];
    vector<int>edge[MAXN];	//邻接表 
    long long values[MAXN];  //存放每个点的值 
    
    void BFS(int now,int father){
    	for(int i=0 ; i<edge[now].size() ; i++){
    		if(edge[now][i] == father)continue;
    		BFS(edge[now][i],now);
    		dp[now][0] = max(dp[edge[now][i]][0],dp[now][0]);
    		dp[now][1] = max(dp[edge[now][i]][1],dp[now][1]); 
    	}
    	long long mid = values[now]+dp[now][1]-dp[now][0];
    	/*前面专门开一个数组values存放值就是为了方便这里*/
    	dp[now][mid<0] += abs(mid);
    }
    
    int main(){
    
    	int N;
    	cin>>N;
    	memset(dp,0,sizeof(dp));
    	memset(values,0,sizeof(values));
    	for(int i=1 ; i<N ; i++){
    		int A,B;
    		scanf("%d %d",&A,&B);
    		edge[A].push_back(B);/*一般都建成无向图以防有坑*/
    		edge[B].push_back(A);
    	}
    	for(int i=1 ; i<=N ; i++){
    		scanf("%lld",&values[i]);
    	}
    	BFS(1,-1);
    	cout<<dp[1][0] + dp[1][1]<<endl;
    	
    	return 0;
    }
     

  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    将Ojective-C代码移植转换为Swift代码
    Swift
    房费制——报表(1)
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514150.html
Copyright © 2011-2022 走看看