学习树的直径前提须知
树的直径 是一棵树的某两个最深的叶子节点的连线,多用于与图论算法嵌套考算法
算法内容
竞赛须要用到的点
一、很简单的算法,不会单独考,学习和熟练使用它的多种状况学习
树的直径略讲
很简单,两次dfsurl
至于为何,能够画图模拟一下,由于一次dfs必然会在一棵子树或者根节点上,每次dfs必然找到一棵子树的最深的叶子节点,那么第二次dfs必然找到另一棵子树的叶子节点,这两点的惟一路径就是整棵树的直径。由这个定理咱们又能够获得,树的直径不止一条。spa
代码以下(参考PT07Z - Longest path in a tree).net
//#define fre yes #include <cstdio> #include <cstring> const int N = 10005; int head[N << 1], to[N << 1], ver[N << 1]; int d[N]; bool Vis[N]; int tot; void addedge(int x, int y) { ver[tot] = y; to[tot] = head[x]; head[x] = tot++; } void dfs(int u) { Vis[u] = true; for (int i = head[u]; ~i; i = to[i]) { int v = ver[i]; if(!Vis[v]) { d[v] = d[u] + 1; dfs(v); } } } int diameter(int n) { int st = 1, mx = -1e9; dfs(st); for (int i = 1; i <= n; i++) { if(d[i] > mx) { mx = d[i]; st = i; } } memset(d, 0, sizeof(d)); memset(Vis, false, sizeof(Vis)); dfs(st); mx = -1e9; for (int i = 1; i <= n; i++) { if(d[i] > mx) { mx = d[i]; } } return mx; } int main() { memset(head, -1, sizeof(head)); static int n; scanf("%d", &n); for (int i = 1; i < n; i++) { int u, v; scanf("%d %d", &u, &v); addedge(u, v); addedge(v, u); } printf("%d\n",diameter(n)); return 0; }
那么也就会存在另外一个问题,让你输出你找的两个节点的最短路径code
挺智障的问题,能够在更新完后获得两个节点来搞,也能够在更新时来搞 前者时间消耗多一点,后者空间消耗多一下 看本身喜爱 这里就不放代码了get