zoukankan      html  css  js  c++  java
  • 【GMOJ4279】树上路径

    题目

    题目链接:https://gmoj.net/senior/#main/show/4279
    有一棵 (n) 个点的无向树,每个点的编号在 (1sim n) 之间,求出每个点所在的最长路。

    思路

    先用 dp 求出每个点到其子树内路径长度最大值和其子树内最长路。
    然后再次搜索每一个点,同时枚举其兄弟节点更新从子树外部连接到这一个点的最长路径。更新答案即可。
    时间复杂度 (O(n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010;
    int n,tot,f[N],head[N],maxl[N];
    
    struct edge
    {
    	int next,to,dis;
    }e[N*2];
    
    void add(int from,int to,int dis)
    {
    	e[++tot].to=to;
    	e[tot].dis=dis;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    void dfs1(int x,int fa)
    {
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (v!=fa)
    		{
    			dfs1(v,x);
    			maxl[x]=max(maxl[x],f[x]+f[v]+e[i].dis);
    			f[x]=max(f[x],f[v]+e[i].dis);
    		}
    	}
    }
    
    void dfs2(int x,int fa,int dis)
    {
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to,maxd=dis;
    		if (v!=fa)
    		{
    			for (int j=head[x];~j;j=e[j].next)
    				if (e[j].to!=fa && e[j].to!=v)
    					maxd=max(maxd,f[e[j].to]+e[j].dis);
    			maxl[v]=max(maxl[v],maxd+e[i].dis+f[v]);
    			dfs2(v,x,maxd+e[i].dis);
    		}
    	}
    }
    
    int main()
    {
    	freopen("tree.in","r",stdin);
    	freopen("tree.out","w",stdout);
    	memset(head,-1,sizeof(head));
    	scanf("%d",&n);
    	for (int i=1,x,y,z;i<n;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z); add(y,x,z);
    	}
    	dfs1(1,0); dfs2(1,0,0);
    	for (int i=1;i<=n;i++)
    		printf("%d
    ",maxl[i]);
    	return 0;
    }
    
  • 相关阅读:
    面试范围
    Spark集群基础概念 与 spark架构原理
    RDD 算子补充
    常用Actoin算子 与 内存管理 、共享变量、内存机制
    常用Transformation算子
    spark core (二)
    Spark 介绍
    JSON对象和string的相互转换
    javascript中substring和substr方法
    mongodb学习相关网址
  • 原文地址:https://www.cnblogs.com/stoorz/p/13864324.html
Copyright © 2011-2022 走看看