zoukankan      html  css  js  c++  java
  • hdu 2196 computer

    hdu 2196

    题意

    给出一棵树,求出树上每一个点在树上走一条简单路径所能走的最长距离。

    解法

    说起来,这是我今天1A的第一题
    我们设
    (up[i]) 表示从这个点向上走到某个点又向下走的最长距离
    (down[i][0]) 表示从这个点出发向他的子树所能走到的最大距离,
    (down[i][1]) 表示从这个点出发向他的子树所能走到的次大距离,
    然后我们就可以愉快的开始转移了。
    我们先dfs一边求出 (down[i][0/1]) ,然后我们再dfs一边求 (up[i])
    首先 (up[i] = up[fa] + dis[i][fa])
    如果 i 在 fa 向下走的最深路径上,那么: (up[i] = max(up[i],dis[i][fa]+down[fa][1]))
    否则: (up[i] = max(up[i],dis[i][fa]+down[fa][0]))
    最后每个点的答案为 (max(up[i],down[i][0]))

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cctype>
    #include <vector>
    #define INF 2139062143
    #define MAX 0x7ffffffffffffff
    #define del(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    template<typename T>
    inline void read(T&x)
    {
        x=0;T k=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
    }
    const int maxn=10000+5;
    int up[maxn];
    int down[maxn][2];
    int n;
    struct Edge{
    	int u,v,w;
    	Edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
    };
    vector<Edge> edge;
    vector<int> G[maxn];
    void add_edge(int u,int v,int w) {
    	edge.push_back(Edge(u,v,w));
    	edge.push_back(Edge(v,u,w));
    	int m=edge.size();
    	G[u].push_back(m-2);
    	G[v].push_back(m-1);
    }
    
    void dfs1(int u,int fa) {
    	for(int i=0;i<G[u].size();i++) {
    		Edge e=edge[G[u][i]];
    		int v=e.v;
    		if(v==fa) continue;
    		dfs1(v,u);
    		if(down[v][0]+e.w>=down[u][0]){
    			down[u][1]=down[u][0];
    			down[u][0]=down[v][0]+e.w;
    		}
    		else if(down[v][0]+e.w>=down[u][1]) down[u][1]=down[v][0]+e.w;
    	}
    }
    void dfs2(int u,int fa) {
    	for(int i=0;i<G[u].size();i++) {
    		Edge e=edge[G[u][i]];
    		int v=e.v;
    		if(v==fa) continue;
    		if(down[u][0]!=down[v][0]+e.w)
    			up[v]=e.w+down[u][0];
    		else up[v]=e.w+down[u][1];
    		up[v]=max(up[u]+e.w,up[v]);
    		dfs2(v,u);
    	}
    }
    void _init() {
    	edge.clear();
    	for(int i=1;i<=n;i++) G[i].clear();
    	del(down,0);del(up,0);
    }
    int main()
    {
    	while(~scanf("%d",&n)){
    		_init();
    		for(int u=2,v,w;u<=n;u++) {
    			read(v);read(w);
    			add_edge(u,v,w);
    		}
    		dfs1(1,1);dfs2(1,1);
    		for(int i=1;i<=n;i++) printf("%d
    ",max(up[i],down[i][0]));
    	}
    	return 0;
    }
    
  • 相关阅读:
    poj 3616 Milking Time
    poj 3176 Cow Bowling
    poj 2229 Sumsets
    poj 2385 Apple Catching
    poj 3280 Cheapest Palindrome
    hdu 1530 Maximum Clique
    hdu 1102 Constructing Roads
    codeforces 592B The Monster and the Squirrel
    CDOJ 1221 Ancient Go
    hdu 1151 Air Raid(二分图最小路径覆盖)
  • 原文地址:https://www.cnblogs.com/mrasd/p/9550879.html
Copyright © 2011-2022 走看看