树的直径概念:一颗树上存在的最长路径。
一:两次bfs求树的直径(不能有负权)
先从任意一点P出发,找离它最远的点Q,再从点Q出发,找离它最远的点W,W到Q的距离就是树的直径
int bfs(int s)
{
memset(dis, 0x3f, sizeof dis);
queue<int> q;
q.push(s);
dis[s] = path[s] = 0;
while (q.size())
{
int x = q.front(); q.pop();
for (int i = head[x]; i; i = Next[i])
{
int y = ver[i];
if (dis[y] == inf)
{
dis[y] = dis[x] + edge[i];
path[y] = i;
q.push(y);
}
}
}
int i, j = 1;
for (i = 1; i <= n; i++)
if (dis[i] > dis[j])
j = i;
return j;
}
int main()
{
//p1,p2为直径的两端点,d为直径
int p1 = bfs(1);
int p2 = bfs(p1);
int d = dis[p2];
return 0;
}
二:DP(可以有负权)
void dp(int x)
{
v[x] = 1;
for (int i = head[x]; i; i = Next[i])
{
int y = ver[i];
if (v[y]) continue;
dp(y);
ans = max(ans, d[x] + d[y] + edge[i]);//ans为最大直径
d[x] = max(d[x], d[y] + edge[i]);
}
}