题目:http://www.lightoj.com/volume_showproblem.php?problem=1094
题意:给定一个由n个点的树,树边都有权值,求树中相距最远的两个点的距离是多少
思路:此题求树的直径。首先任选一点做dfs,求出此点到其他点的距离,然后从距离最远的点(此点为树的直径的一个端点)开始再做一次dfs,求出到所有点的距离,此时的最大距离就是树上两点间的最大距离,也就是树的直径。证明网上一大堆
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <queue> #include <map> using namespace std; const int N = 30010, INF = 0x3f3f3f3f; struct edge { int to, cost, next; }g[N*2]; int cnt, head[N]; bool vis[N]; int dep[N]; int n, cas, res; void add_edge(int v, int u, int cost) { g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++; } void dfs(int v, int d) { vis[v] = true, dep[v] = d; if(dep[v] > dep[res]) res = v;//记录距离最大的那个点 for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(! vis[u]) dfs(u, dep[v] + g[i].cost); } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); int v, u, c; cnt = 0; memset(head, -1, sizeof head); for(int i = 1; i <= n - 1; i++) { scanf("%d%d%d", &v, &u, &c); add_edge(v, u, c), add_edge(u, v, c); } memset(vis, 0, sizeof vis); res = 0; dfs(0, 0); memset(vis, 0, sizeof vis); dfs(res, 0); printf("Case %d: %d\n", ++cas, dep[res]); } return 0; }