hihoCoder #1050 : 树中的最长路
写这篇博客的目的有两个
1.总结一下自己的心得,以免后来会忘掉。
2.搜了好多别人的博客,好多都是模棱两可,比如在说明 u 不是直径上的点的时候,随便说了一下 u 的最长路 一定与直径相交,并没有说明为什么,借此机会,我就说明一下。
树的直径(树的最长路)
下面是定理和证明:
定理:
从树的任意一点 u 出发,DFS 到最长路终点 s,再从 s 点 DFS 到最长路的终点 t , 那么 s - t 就是树的直径。且从 u 出发的最长路的终点一定为直径的某一个端点。
证明:
在证明之前,说个常识,如果 s 是直径上的一点,那么从 s 出发的最长路就是直径,终点 t 就是直径的终点。如果这个常识不懂得话,后面的证明白说。如果 u 是直径上的一点,那么假设s 不是直径的端点, 那么必然存在一个点 x 使得 u - x > u - s,与定理矛盾。如果 u 不是直径上的一点,那么又分为两种:
1)从u的出发到达的最长路的终点为 x ,且与 s - t 有交点 z,那么 u - x > u - s,所以 z - x > z - s,矛盾。
2)从u的出发到达的最长路的终点为 x ,且与 s - t 没有交点。设从 u - t 的最短路与s - t 的交点为 z。那么 u - x > u - t = u - z - t,x - s = x - u - z - s;所以 x - s > s - t ,与 s - t 是直径矛盾。所以必有交点。如果不懂,可以看这里点击打开链接。
#include <map> #include <set> #include <list> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <cstdio> #include <vector> #include <sstream> #include <cstdlib> #include <complex> #include <cstring> #include <iostream> #include <algorithm> #define REP(i,N) for (int i = 0;i < (N);i++) #define REP_1(i,N) for (int i = 1;i < (N);i++) #define REP_2(i,be,en) for (int i = (be);i < (en);i++) #define DWN(i,N) for (int i = (N);i >= 0;i--) #define DWN_1(i,N) for (int i = (N);i >= 1;i--) #define DWN_2(i,en,be) for (int i = (en);i >= (be);i--) #define FR(N) freopen((N),"r",stdin) #define FW(N) freopen((N),"w",stdout) #define GETS(ch) fgets((ch),MAXN,stdin); #define INF 0x3f3f3f3f #define MAXN 100010 using namespace std; typedef long long LL; typedef map<string,int> MINT; typedef vector<int> VINT; typedef set<int> SINT; int N;//树的节点数 vector <VINT> G;// 存储树的路径 int Length;// 树的长度 int s;// s 为 第一次搜索获得直径的起点 int dfs(int u,int deep,int f) { // 求树的最长路径,u 为当下要搜的节点,deep 为当前的长度, f 为 u 的父亲节点 if (deep > Length) { Length = deep; s = u; } int len = G[u].size(); REP(i,len) { if (G[u][i] != f) { dfs(G[u][i],deep + 1,u); } } } int main () { cin >> N; G.resize(N + 1); REP(i,N - 1) { int c ,f; cin >> f >> c; G[f].push_back(c); G[c].push_back(f); } Length = 0;// 期初长度为0 dfs(1,0,0);// 从任意节点开始搜 in [1...N],求出s Length = 0;// 长度归0,重新从s开始 dfs(s,0,0); cout << Length << endl; }