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
    }
    
  • 相关阅读:
    MySQL数据库命令行界面不支持中文
    mysqldump使用方法(MySQL数据库的备份与恢复)
    MySQL性能测试初试(1)--sysbench
    composer安装
    Java关键字[static].md
    Docker容器
    Docker概述及安装
    Docker镜像
    定时任务[crontab]
    Linux下的curl工具
  • 原文地址:https://www.cnblogs.com/lautsie/p/3367288.html
Copyright © 2011-2022 走看看