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;
    }
    
  • 相关阅读:
    软件工程-事后Postmortem 会议
    软件工程-项目复审
    团队作业-冲刺博客(日更)
    团队作业-冲刺博客(任务与计划)
    团队作业-需求改进&系统设计
    软件工程团队作业-需求规格说明书
    TooBug,出撃!
    FileReader
    Javascript刷新页面的几种方法:
    软件工程-个人项目
  • 原文地址:https://www.cnblogs.com/stoorz/p/13864324.html
Copyright © 2011-2022 走看看