zoukankan      html  css  js  c++  java
  • 树的直径

    求一棵树上距离最远的两个顶点的距离,就是求树的直径。做法是两次BFS或DFS。设r是树T的根,u是距离r最远的结点,v是距离u最远的结点。则树的直径就是d(u , v)。
    可以用反证法证明:http://wenku.baidu.com/view/00d9168984868762caaed5a4.html (图的直径可以用Floyd做:http://blog.csdn.net/sunmenggmail/article/details/7739419
    下面是一个DFS实现,里面用无向图(就是对称的有向图)来表示树,所以很方便从任何一个点DFS。做完DFS,返回节点号就行了。两次调用完,ans_path里记录的就是直径。有道POJ的习题有空可以练一下:http://poj.org/problem?id=1985

    在需要很多次调用DFS的情况下,多次memset visited[N]会耗费许多时间(因为N很大),可以加个变量visited_id,每次DFS,visited_id++,然后判断visited[N] == visited_id就行了。

    #include <vector>;
    using namespace std;
    
    const static int N = 200003;
    bool visited[N];
    vector<int> curr_path;
    vector<int> ans_path;
    void dfs_helper(vector<vector<int>> &tree, int root, vector<int> &curr, vector<int> &ans) {
    	if (visited[root]) {
    		return;
    	}
    	visited[root] = true;
    	curr.push_back(root);
    	if (curr.size() > ans.size()) {
    		ans = curr; // vector copy, but most d times, d is the length of the diameter
    	}
    	int m = tree[root].size();
    	for (int i = 0; i < m; i++) {
    		dfs_helper(tree, tree[root][i], curr, ans);
    	}
    	curr.pop_back();
    }
    
    int dfs(vector<vector<int>> &tree, int root) {
    	curr_path.clear();
    	ans_path.clear();
    	memset(visited, false, sizeof(visited));
    	dfs_helper(tree, root, curr_path, ans_path);
    	return ans_path.back();
    }
    
    int main()
    {
    	// int root = dfs(tree, 0);
    	// dfs(tree, root);
    	// then the ans_path is the shortest path in the tree
    }
    
  • 相关阅读:
    Java 中的POJO和JavaBean 的区别
    设计模式的六大原则
    AOP
    Jetbrains 全家桶
    centos7 如何关闭防护墙
    Java 面试题常见范围
    putty readme
    单机环境
    flask-caching缓存
    1.restful 规范与APIView
  • 原文地址:https://www.cnblogs.com/lautsie/p/3367288.html
Copyright © 2011-2022 走看看