zoukankan      html  css  js  c++  java
  • 点对最大值 (换根DP)

    “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)

    换根来一波

    https://ac.nowcoder.com/acm/contest/5758/A

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6 + 111;
    ll list[maxn];
    struct Node {
    	int p;
    	ll len;
    	int nxt;
    }G[2*maxn];
    int head[maxn];
    
    
    int z;
    void add(int x, int y,ll len) {
    	G[++z].p = y;
    	G[z].nxt = head[x];
    	G[z].len = len;
    	head[x] = z;
    }
    ll dp[maxn];//最大
    ll dp2[maxn];//第二大
    
    int cal(int x, ll val) {//x节点放进去一个val
    	if (val >= dp[x]) {
    		dp2[x] = dp[x];
    		dp[x] = val;
    	}
    	else {
    		if (val >= dp2[x]) {
    			dp2[x] = val;
    		}
    	}
    	return 0;
    }
    int de[maxn];
    
    int dfs1(int x, int fa) {
    	for (int i = head[x]; i; i = G[i].nxt) {
    		int p = G[i].p;
    		ll ln = G[i].len;
    		if (p == fa) continue;
    		dfs1(p, x);
    		ll a = list[x] + ln + list[p];  
    		ll b = dp[p] - list[p] + ln + list[x];
    
    		if (a > b) {
    			cal(x, a);
    		}
    		else {
    			cal(x, b);
    		}
    		
    	}
    	return 0;
    }
    
    
    int dfs2(int x, int fa) {
    	for (int i = head[x]; i; i = G[i].nxt) {
    		int p = G[i].p;
    		ll ln = G[i].len;
    		if (p == fa) continue;
    		ll c = list[x] + list[p] + ln;
    		
    		if (de[p] == 1) {
    			if (list[x] + ln + list[p] == dp[x]) {//在线上
    				ll a = dp2[x] - list[x] + ln + list[p];
    				a = max(a, c);
    				cal(p,a);
    			}
    			else {
    				ll a = dp[x] - list[x] + ln + list[p];
    				a = max(a, c);
    				cal(p, a);
    			}
    		}
    		else {
    			if (dp[p] - list[p] + ln + list[x] == dp[x]|| dp[x] == list[p] + list[x] + ln) {
    				ll a = dp2[x] - list[x] + ln + list[p];
    				a = max(a, c);
    				cal(p, a);
    			}
    			else {
    				ll a = dp[x] - list[x] + ln + list[p];
    
    				a = max(a, c);
    
    				cal(p, a);
    			}
    		}
    		dfs2(p, x);
    	}
    	return 0;
    }
    
    int n, m;
    int main() {
    	int t;
    	scanf("%d", &t);
    	while (t--) {
    		scanf("%d", &n);
    		for (int i = 0; i <= n; i++) {
    			head[i] = 0;
    			de[i] = 0;
    
    			dp[i] = -1e18;
    			dp2[i] = -1e18;
    		}
    		z = 0;
    
    		int x;
    		ll len;
    		int be, en;
    		for (int i = 2; i <= n; i++) {
    			scanf("%d %lld", &x, &len);
    			add(x, i, len);
    			add(i, x, len);
    			de[x]++;
    			de[i]++;
    			
    		}
    
    		for (int i = 1; i <= n; i++) {
    			scanf("%lld", &list[i]);
    			//dp[i] = 2 * list[i];
    		}
    
    
    		dfs1(1, -1);
    		dfs2(1, -1);
    	
    		long long ans = -1e18;
    		for (int i = 1; i <= n; i++) {
    			
    			ans = max(ans, dp[i]);
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    
    }
    
    /*
    21312
    11
    1 2 1
    2 4 4s
    2 3 3
    3 5 7
    3 6 8
    1 7 2
    7 8 5
    7 9 6
    8 10 9
    9 11 10
    1 2 3 4 5 6 7 8 9 10 11
    
    
    */
    

      

    寻找真正的热爱
  • 相关阅读:
    Vue Hooks
    React初识-Hooks
    React-JSX初识
    css基础知识
    发布-订阅者模式
    Map和Set
    数据类型
    tcp三次握手以及tcp三次握手一句话总结
    网页布局相关
    浏览器渲染页面的流程
  • 原文地址:https://www.cnblogs.com/lesning/p/13019900.html
Copyright © 2011-2022 走看看