• 小白月赛22 B : 树上子链


    B:树上子链

    考察点 : 树的直径
    坑点 :   long long, 是点权不是边权
             一个点也算一条链
    

    析题得侃:

    关于树的直径
    这道题考察的是树的直径,最好用树形DP来写,具体解释详见上述博客,
    这道题不友好的地方是把原先的边权搞成了点权,这就让人十分的头疼,
    一头疼这道题就凉凉,哈哈,可能还是对这个知识点掌握的不够到位吧

    Code :

    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    typedef long long LL;
    
    int head[maxn],Next[maxn << 1],ver[maxn << 1];
    LL vis[maxn],a[maxn],dist[maxn];
    
    int n,tot = 0;
    
    LL ans = -INF;
    
    int main(void) {
    	void add(int u,int v);
    	void dp(int u);
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%lld",&a[i]);
                    // 一个点也可以是一条链
                    // 先取一个最大值
    		ans = max(ans,a[i]);
    	}
    	int u,v;
    	for(int i = 1; i < n; i ++) {
    		scanf("%d%d",&u,&v);
                    // 双向边
    		add(u,v);
    		add(v,u);
    	}
    	dp(1);
    	cout << ans << endl;
    	return 0;
    }
    
    void add(int u,int v) {
    	ver[++ tot] = v,Next[tot] = head[u];
    	head[u] = tot;
    	return ;
    }
    
    void dp(int u) {
    	LL mx = 0;
    	vis[u] = 1;
            // 初始化
    	dist[u] = a[u];
    	for(int i = head[u]; i; i = Next[i]) {
    		int y = ver[i];
    		if(vis[y]) continue;
                    // 向叶子节点进行递归
    		dp(y);
                    // 树的直径 = 最长链 + 次长链
    		ans = max(ans,mx + a[u] + dist[y]);
                    // 更新最长链(实际上是一个最大节点)
    		mx = max(mx,dist[y]);
    	}
            // 更新其父节点
    	dist[u] += mx;
    	return ;
    }
    
  • 相关阅读:
    tensorflow学习3---mnist
    tensorflow学习2-线性拟合和神经网路拟合
    关于泛型数据结构中OrderBy的使用
    敏捷开发之观察者模式
    敏捷开发之设计文档
    C#算法实现获取树的高度
    武林高手?敏捷开发,唯velocity取胜
    C#接口多继承方法重名问题
    .Net平台技术栈?不止于此
    浅谈C#中Tuple和Func的使用
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12354191.html
Copyright © 2020-2023  润新知