zoukankan      html  css  js  c++  java
  • SGU 149. Computer Network

    时间限制:0.25s

    空间限制:4M;

    题意:

           给出一颗n(n<=10000)个节点的树,和n-1条边的长度。求出这棵树每个节点到最远节点的距离;


    Solution:

                 对于一个节点,我们可以用DFS,在O(n)的时间内求出它的最远节点的距离.

                 显然对于10000个节点,不可能将每一个节点都这样求.

                 那么我们来看看,对于一个已经求过的节点我们可以做什么:

                       假设,有节点k,他有子节点p,两者距离为d

                       已经求得它的最远节点距离为dis1,

                       这时对他的子节点p来说,有两种情况:

                            一种是:p在k的与最远节点的路径上.

                                     这时p的最远距离等于max(dis1-d,k的次远距离+d);

                           另一种是:p不在k的最远路径上.

                                      此时p的最远距离等于max(dis1+d,p向下的最远距离);

                  通过上面我们发现,我们需要一个节点的最远距离和次远距离以及p向下的最远距离.

                  幸运的是这三个量都可以通过一次对根的DFS在O(n)的时间内求出.

                  最后再从根进行一次DFS遍求出每个节点的最远距离和次远距离就可以求出所有的答案了.

                  总的时间复杂度O(n),空间复杂度O(n);

    code

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <utility>
    using namespace std;
    
    #define mp make_pair
    #define fi first
    #define se second
    #define sz(x) ((int) (x).size())
    #define rd(a) scanf("%d",&a)
    #define rdd(a,b) scanf("%d%d",&a,&b);
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define pb push_back
    
    typedef pair<int, int> ii;
    typedef vector<ii> vii;
    const int INF = 11111;
    
    vii edge[INF];
    int dis[INF][2], ans[INF];
    int n, x, y;
    int dfs (int x) {
    	dis[x][0] = 0;
    	rep (i, 0, sz(edge[x]) - 1) {
    		ii v = edge[x][i];
    		int tem = dfs (v.fi)+v.se;
    		rep (i, 0, 1)   if (tem > dis[x][i]) swap (tem, dis[x][i]);
    	}
    	return dis[x][0];
    }
    void DP (int x) {
    	int tem;
    	ans[x] = dis[x][0];
    	rep (i, 0, sz (edge[x]) - 1) {
    		ii v = edge[x][i];
    		if (dis[v.fi][0] + v.se == dis[x][0])
    			tem = dis[x][1] + v.se;
    		else
    			tem = dis[x][0] + v.se;
    		rep (i, 0, 1) if (tem > dis[v.fi][i]) swap (tem, dis[v.fi][i]);
    		DP (v.fi);
    	}
    }
    int main() {
    	rd (n);
    	rep (i, 2, n) {
    		rdd (x, y);
    		edge[x].pb (mp (i, y) );
    	}
    	dfs (1);
    	DP (1);
    	rep (i, 1, n) printf ("%d
    ", ans[i]);
    }
    

      

                  

  • 相关阅读:
    2018-2019-1 20189221 《从问题到程序》第 6 周学习总结
    2018-2019-1 20189221 《Linux内核原理与分析》第七周作业
    《文献管理与信息分析》第 2 周学习总结
    2018-2019-1 20189221 《从问题到程序》第 5 周学习总结
    2018-2019-1 20189221 《Linux内核原理与分析》第六周作业
    2018-2019-1 20189206 《深入理解计算机系统》第一章学习笔记
    2018-2019-1 20189206 《从问题到程序》速读
    2018-2019-1 20189206 《深入理解计算机系统》速读
    2018-2019-1 20189206 《构建之法》速读
    2018-2019-1 20189206 《Linux内核原理与分析》第二周作业
  • 原文地址:https://www.cnblogs.com/keam37/p/3844966.html
Copyright © 2011-2022 走看看