1.​​题目链接​​。求树的直径裸题,树的直径定义为树上距离最远的两个点。至于求法,bfs,dfs,树DP都可以。简单说一下如何bfs,因为我觉得这个最好实现。(但是据说没办法处理负边权)。其实bfs很简答,就是先随机找一个点,然后找出距离这个点最远的点,再从这个点bfs找出距离这个点最远的点,就是直径。为什么??我举个例子,在一张图像中,是一个人,你想知道这个人的身高,那么你可以现在图上任选一个点,找到距离这个点最远的点,这个时候你找到的点一定是头部或者脚,那么再从这个地方出发,找距离这个点最远的点,如果你开始在头部,那么就可以找到脚,反之亦然。(当然这里只是举一个例子,真正在图像中不是这么简单的,因为你还可能找到四肢的其他地方,控制一下方向就好了)。所以我们两次bfs,第一次一定可以找到最长链上的一个点,然后从这个点出发找到最长的链就是直径。(输入很迷)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

const int MAXN = 10010;
const int MAXE = 20010;

int dis[MAXN], head[MAXN];
int to[MAXE], Next[MAXE], cost[MAXE];
int n, ecnt;

void init() {
memset(head, -1, sizeof(head));
ecnt = 0;
}

void add_edge(int u, int v, int c) {
to[ecnt] = v; cost[ecnt] = c; Next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cost[ecnt] = c; Next[ecnt] = head[v]; head[v] = ecnt++;
}

int bfs(int st) {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(st);
dis[st] = 0;
while (!que.empty()) {
int u = que.front(); que.pop();
for (int p = head[u]; ~p; p = Next[p]) {
int& v = to[p];
if (dis[v] > dis[u] + cost[p]) {
dis[v] = dis[u] + cost[p];
que.push(v);
}
}
}
int ed = st;
for (int i = 1; i <= n; ++i)
if (dis[i] > dis[ed]) ed = i;
return ed;
}

int main() {
init();
n = 1;
int u, v, c;
while (scanf("%d%d%d", &u, &v, &c) != EOF)
{
add_edge(u, v, c);
++n;
}
u = bfs(1);
v = bfs(u);
printf("%d\n", dis[v]);
}