最近在复习比较简单的知识,顺便当整理代码吧。
树的直径是一个经典问题,即求树上最远两点的距离。
思路一:
任取一个点,求这个点的最远点的最远点,两遍bfs即可。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <queue> 9 #include <stack> 10 #include <vector> 11 #include <map> 12 #include <set> 13 #include <functional> 14 #include <cctype> 15 #include <time.h> 16 17 using namespace std; 18 19 const int INF = 1<<30; 20 21 struct Graph { 22 static const int MAXN = (int) 1e5+55; 23 static const int MAXM = MAXN*2; 24 25 int head[MAXN]; 26 int next[MAXM], to[MAXM], use; 27 28 inline void init() { 29 memset(head, -1, sizeof(head)); 30 use = 0; 31 } 32 33 inline void addEdge(int u, int v) { 34 next[use] = head[u]; 35 to[use] = v; 36 head[u] = use++; 37 } 38 }; 39 40 const int MAXN = (int) 1e5+55; 41 42 Graph G; 43 int Que[MAXN]; 44 int d[MAXN]; 45 int n; 46 47 void bfs(int st) { 48 memset(d, -1, sizeof(d)); 49 int l = 0, r = 0; 50 d[st] = 0; 51 Que[r++] = st; 52 while (l<r) { 53 int u = Que[l++]; 54 for (int p = G.head[u]; p != -1; p = G.next[p]) { 55 int v = G.to[p]; 56 if (d[v]!=-1) continue; 57 d[v] = d[u] + 1; 58 Que[r++] = v; 59 } 60 } 61 } 62 63 void solve() { 64 bfs(1); 65 bfs(Que[n-1]); 66 printf("%d ", d[Que[n-1]]); 67 } 68 69 int main() { 70 #ifdef Phantom01 71 freopen("1050.txt", "r", stdin); 72 #endif //Phantom01 73 74 while (scanf("%d", &n)!=EOF) { 75 G.init(); 76 int u, v; 77 for (int i = 1; i < n; i++) { 78 scanf("%d%d", &u, &v); 79 G.addEdge(u, v); 80 G.addEdge(v, u); 81 } 82 solve(); 83 } 84 85 return 0; 86 }
另一种思路是树形dp,一棵树中的最长路要么在子树中,要么经过根。枚举每棵子树的最大深度和次大深度即可。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <queue> 9 #include <stack> 10 #include <vector> 11 #include <map> 12 #include <set> 13 #include <functional> 14 #include <cctype> 15 #include <time.h> 16 17 using namespace std; 18 19 const int INF = 1<<30; 20 21 struct Graph { 22 static const int MAXN = (int) 1e5+55; 23 static const int MAXM = MAXN*2; 24 25 int head[MAXN]; 26 int next[MAXM], to[MAXM], use; 27 28 inline void init() { 29 memset(head, -1, sizeof(head)); 30 use = 0; 31 } 32 33 inline void addEdge(int u, int v) { 34 next[use] = head[u]; 35 to[use] = v; 36 head[u] = use++; 37 } 38 }; 39 40 Graph G; 41 42 const int MAXN = (int) 1e5+55; 43 44 int dp[MAXN]; 45 int ans; 46 47 int dfs(int u, int pre, int cnt) { 48 int fi = 0, se = 0; 49 int t; 50 51 for (int p = G.head[u]; p != -1; p = G.next[p]) { 52 int v = G.to[p]; 53 if (v==pre) continue; 54 t = dfs(v, u, cnt+1); 55 if (t>fi) { se = fi; fi = t; } 56 else if (t>se) se = t; 57 } 58 ans = max(ans, max(fi+cnt, fi+se)); 59 return fi+1; 60 } 61 62 int main() { 63 #ifdef Phantom01 64 freopen("1050.txt", "r", stdin); 65 #endif //Phantom01 66 67 int n, u, v; 68 while (scanf("%d", &n)!=EOF) { 69 G.init(); 70 for (int i = 1; i < n; i++) { 71 scanf("%d%d", &u, &v); 72 G.addEdge(u, v); 73 G.addEdge(v, u); 74 } 75 ans = 0; 76 dfs(1, 1, 0); 77 printf("%d ", ans); 78 } 79 80 return 0; 81 }
顺便说一下,hiho上这个题的数据比较弱,开始我几个错误的代码都A了。