树的直径是一棵树中最长的路径。
怎么确定树的直径呢?
先任意选一个点,找到距离它最远的点x,然后再找距离点x最远的点y,xy就是直径。
(易用反证法证明出x就是直径上的一点)
问题等价于求最长路径
又见到个dfs,这个第二个参数表该点的父亲节点,其功能等价于st数组
这个dfs呢,目的就是把所有的dist 得到。
给出四种DFS,可继续理解dfs
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
vector<PII> v[N];
int n;
int dist[N];
void dfs(int u, int father, int distance)
{
dist[u] = distance;
for (auto node : v[u])
if (node.x != father)
dfs(node.x, u, distance + node.y);
}
int main()
{
cin >> n;
for (int i = 1;i <= n - 1;i++)
{
int a, b, w;
cin >> a >> b >> w;
v[a].push_back({ b,w });
v[b].push_back({ a,w });
}
dfs(1, -1, 0);//因为是无向图,防止遍历回去
int u = 1;
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
// memset(dist, 0, sizeof dist);//因为下个dfs重置dist的 没必要加这行
dfs(u, -1, 0);
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
int s = dist[u];
cout << 10 * s + (s + 1ll) * s / 2;
}
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1e5+10;
typedef pair<int, int> PII;
vector<PII> v[N];
int n;
int dist[N];
bool st[N];
void dfs(int u, int distance)
{
st[u]=true;
dist[u] = distance;
for (auto node : v[u])
if (!st[node.x])
dfs(node.x, distance + node.y);
st[u]=false;
}
int main()
{
cin >> n;
for (int i = 1;i <= n - 1;i++)
{
int a, b, w;
cin >> a >> b >> w;
v[a].push_back({ b,w });
v[b].push_back({ a,w });
}
dfs(1, 0);
int u = 1;
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
dfs(u, 0);
// memset(dist, 0, sizeof dist);
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
int s = dist[u];
cout << 10 * s + (s + 1ll) * s / 2;
}
这个需要memset(st,false,sizeof st) 👇
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
vector<PII> v[N];
int n;
int dist[N];
bool st[N];
void dfs(int u, int distance)
{
dist[u] = distance;
for (auto node : v[u])
{
if (!st[node.x])
{
st[node.x] = true;
dfs(node.x, distance + node.y);
st[node.x] = false;
}
}
}
int main()
{
cin >> n;
for (int i = 1;i <= n - 1;i++)
{
int a, b, w;
cin >> a >> b >> w;
v[a].push_back({ b,w });
v[b].push_back({ a,w });
}
st[1]=true;
dfs(1, 0);
int u = 1;
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
memset(st,false,sizeof st);//只需要st[1]=false就可了,其他的都回溯变成false了
st[u] = true;
dfs(u, 0);
// memset(dist, 0, sizeof dist);
for (int i = 1;i <= n;i++)
if (dist[i] > dist[u])
u = i;
int s = dist[u];
cout << 10 * s + (s + 1ll) * s / 2;
}
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
vector<PII> v[N];
int n;
bool st[N];
int res, id;
void dfs(int u,int distance)
{
st[u] = true;
if (distance > res)
res = distance, id = u;
for (auto node : v[u])
{
if(!st[node.x])
dfs(node.x, distance + node.y);
}
st[u] = false;
}
int main()
{
cin >> n;
for (int i = 1;i <= n - 1;i++)
{
int a, b, w;
cin >> a >> b >> w;
v[a].push_back({ b,w });
v[b].push_back({ a,w });
}
dfs(1,0);
int u = id;
//res = 0;//这个其实不用因为下个dfs求的直径是最长的
dfs(u,0);
int s = res;
cout << 10 * s + (s + 1ll) * s / 2;
}
L2-031 深入虎穴——最短路模型_他不是混子QAQ的博客-CSDN博客
第四个的dfs与👆同