|
|
|
@ -40,14 +40,14 @@ $−10^5≤c_i≤10^5$
|
|
|
|
|
|
|
|
|
|
### 二、朴素版本$dfs$【不能$AC$】
|
|
|
|
|
朴素$dfs$: 对每个点求最远点最大距离, 所有结果的$max$就是结果.
|
|
|
|
|
通过 $10/16$. 然后$TLE$, 效果不是很理想。
|
|
|
|
|
通过 $11/17$. 然后$TLE$, 效果不是很理想。
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const int N = 10010, M = 20010;
|
|
|
|
|
const int N = 10010, M = N << 1;
|
|
|
|
|
// 暴力搜索,从每个节点为根出发,遍历整根树,找出距离自己的最大距离,然后每个最大距离取min
|
|
|
|
|
// 10/16,其它TLE,无法AC
|
|
|
|
|
// 11/17,其它TLE,无法AC
|
|
|
|
|
int n;
|
|
|
|
|
int ans; // 树的直径
|
|
|
|
|
// 邻接表
|
|
|
|
@ -55,15 +55,13 @@ int e[M], h[N], idx, w[M], ne[M];
|
|
|
|
|
void add(int a, int b, int c = 0) {
|
|
|
|
|
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
|
|
|
|
|
}
|
|
|
|
|
int st[N];
|
|
|
|
|
|
|
|
|
|
void dfs(int u, int sum) {
|
|
|
|
|
st[u] = 1;
|
|
|
|
|
void dfs(int u, int fa, int sum) {
|
|
|
|
|
if (sum > ans) ans = sum;
|
|
|
|
|
for (int i = h[u]; ~i; i = ne[i]) {
|
|
|
|
|
int j = e[i];
|
|
|
|
|
if (st[j]) continue; // 不走回头路
|
|
|
|
|
dfs(j, sum + w[i]);
|
|
|
|
|
int v = e[i];
|
|
|
|
|
if (v == fa) continue; // 不走回头路
|
|
|
|
|
dfs(v, u, sum + w[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -79,10 +77,7 @@ int main() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 多次dfs,是TLE的罪魁祸首
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
memset(st, 0, sizeof st);
|
|
|
|
|
dfs(i, 0);
|
|
|
|
|
}
|
|
|
|
|
for (int i = 1; i <= n; i++) dfs(i, 0, 0);
|
|
|
|
|
|
|
|
|
|
// 输出结果
|
|
|
|
|
printf("%d", ans);
|
|
|
|
@ -105,14 +100,14 @@ int main() {
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
通过了 $14/16$个数据,剩余两个测试点,居然是$WA$,真是,唉~
|
|
|
|
|
通过了 $15/17$个数据,剩余两个测试点,居然是$WA$,真是,唉~
|
|
|
|
|
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const int N = 10010, M = 20010;
|
|
|
|
|
const int N = 10010, M = N << 1;
|
|
|
|
|
|
|
|
|
|
int ans; // 保存最长路径
|
|
|
|
|
int t; // 保存找到的最远点
|
|
|
|
@ -123,18 +118,16 @@ int e[M], h[N], idx, w[M], ne[M];
|
|
|
|
|
void add(int a, int b, int c = 0) {
|
|
|
|
|
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
|
|
|
|
|
}
|
|
|
|
|
int st[N];
|
|
|
|
|
|
|
|
|
|
void dfs(int u, int sum) {
|
|
|
|
|
st[u] = 1;
|
|
|
|
|
void dfs(int u, int fa, int sum) {
|
|
|
|
|
if (sum > ans) {
|
|
|
|
|
ans = sum; // 记录最大距离
|
|
|
|
|
t = u; // 记录最远的点t1
|
|
|
|
|
}
|
|
|
|
|
for (int i = h[u]; ~i; i = ne[i]) {
|
|
|
|
|
int j = e[i];
|
|
|
|
|
if (st[j]) continue;
|
|
|
|
|
dfs(j, sum + w[i]);
|
|
|
|
|
int v = e[i];
|
|
|
|
|
if (v == fa) continue;
|
|
|
|
|
dfs(v, u, sum + w[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -146,11 +139,9 @@ int main() {
|
|
|
|
|
cin >> a >> b >> c;
|
|
|
|
|
add(a, b, c), add(b, a, c);
|
|
|
|
|
}
|
|
|
|
|
memset(st, 0, sizeof st);
|
|
|
|
|
dfs(1, 0); // 先找到点距离点1最远的点t1
|
|
|
|
|
dfs(1, 0, 0); // 先找到点距离点1最远的点t1
|
|
|
|
|
|
|
|
|
|
memset(st, 0, sizeof st);
|
|
|
|
|
dfs(t, 0); // 找到距离点t1->t2最远的点t1
|
|
|
|
|
dfs(t, 0, 0); // 找到距离点t1->t2最远的点t1
|
|
|
|
|
|
|
|
|
|
printf("%d", ans);
|
|
|
|
|
return 0;
|
|
|
|
@ -194,50 +185,47 @@ int main() {
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
const int N = 10010, M = N << 1;
|
|
|
|
|
int n; // n个结点
|
|
|
|
|
|
|
|
|
|
const int N = 10010; // 点数上限
|
|
|
|
|
const int M = N * 2; // 边数上限
|
|
|
|
|
int n;
|
|
|
|
|
int ans;
|
|
|
|
|
int d1[N], d2[N]; // 最长,次长
|
|
|
|
|
int st[N];
|
|
|
|
|
// 链式前向星
|
|
|
|
|
int h[N], e[M], w[M], ne[M], idx;
|
|
|
|
|
void add(int a, int b, int c) {
|
|
|
|
|
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dfs(int u) {
|
|
|
|
|
st[u] = 1;
|
|
|
|
|
for (int i = h[u]; ~i; i = ne[i]) {
|
|
|
|
|
int j = e[i];
|
|
|
|
|
if (st[j]) continue;
|
|
|
|
|
|
|
|
|
|
// 走j子树,完成后,j子树中每个节点的d1[j],d2[j]都已经准备好,u节点可以直接利用
|
|
|
|
|
dfs(j);
|
|
|
|
|
int ans; // 答案,直径
|
|
|
|
|
int mx1[N], mx2[N]; // mx1[i],mx2[i]:经过i点的最长,次长长度是多少
|
|
|
|
|
|
|
|
|
|
// d1[u]:最长路径,d2[u]:次长路径
|
|
|
|
|
if (d1[j] + w[i] >= d1[u])
|
|
|
|
|
d2[u] = d1[u], d1[u] = d1[j] + w[i]; // 最长路转移
|
|
|
|
|
else if (d1[j] + w[i] > d2[u])
|
|
|
|
|
d2[u] = d1[j] + w[i]; // 次长路转移
|
|
|
|
|
void dfs(int u, int fa) {
|
|
|
|
|
for (int i = h[u]; ~i; i = ne[i]) {
|
|
|
|
|
int v = e[i];
|
|
|
|
|
if (v == fa) continue; // v点访问过了
|
|
|
|
|
|
|
|
|
|
// 走v子树,完成后,v子树中每个节点的mx1[v],mx2[v]都已经准备好,u节点可以直接利用
|
|
|
|
|
dfs(v, u);
|
|
|
|
|
|
|
|
|
|
// w[i]:u->v的路径长度,mx1[u]:最长路径,mx2[u]:次长路径
|
|
|
|
|
int x = mx1[v] + w[i];
|
|
|
|
|
if (mx1[u] <= x) // v可以用来更新u的最大值
|
|
|
|
|
mx2[u] = mx1[u], mx1[u] = x; // 最长路转移
|
|
|
|
|
else if (mx2[u] < x)
|
|
|
|
|
mx2[u] = x; // 次长路转移
|
|
|
|
|
}
|
|
|
|
|
// 更新结果
|
|
|
|
|
ans = max(ans, d1[u] + d2[u]);
|
|
|
|
|
ans = max(ans, mx1[u] + mx2[u]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
cin >> n;
|
|
|
|
|
// 初始化邻接表
|
|
|
|
|
memset(h, -1, sizeof h);
|
|
|
|
|
for (int i = 1; i < n; i++) {
|
|
|
|
|
memset(h, -1, sizeof h); // 初始化邻接表
|
|
|
|
|
for (int i = 1; i < n; i++) { // n-1条边
|
|
|
|
|
int a, b, c;
|
|
|
|
|
cin >> a >> b >> c;
|
|
|
|
|
add(a, b, c), add(b, a, c);
|
|
|
|
|
add(a, b, c), add(b, a, c); // 换根dp一般用于无向图
|
|
|
|
|
}
|
|
|
|
|
// 任选一个点作为根节点
|
|
|
|
|
dfs(1);
|
|
|
|
|
// 输出答案
|
|
|
|
|
printf("%d", ans);
|
|
|
|
|
dfs(1, 0); // 任选一个点作为根节点,此处选择的是肯定存在的1号结点
|
|
|
|
|
cout << ans << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
```
|