链接:https://ac.nowcoder.com/acm/contest/1109/H
来源:牛客网
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld
题目描述
In ICPCCamp there were n towns conveniently numbered with 1,2,…,n1, 2, \dots, n1,2,…,n
connected with (n - 1) roads.
The i-th road connecting towns aia_iai and bib_ibi has length cic_ici.
It is guaranteed that any two cities reach each other using only roads.
Bobo would like to build (n - 1) highways so that any two towns reach each using *only highways*.
Building a highway between towns x and y costs him δ(x,y)\delta(x, y)δ(x,y) cents,
where δ(x,y)\delta(x, y)δ(x,y) is the length of the shortest path between towns x and y using roads.
As Bobo is rich, he would like to find the most expensive way to build the (n - 1) highways.
输入描述:
The input contains zero or more test cases and is terminated by end-of-file. For each test case: The first line contains an integer n. The i-th of the following (n - 1) lines contains three integers aia_iai, bib_ibi and cic_ici. * 1≤n≤1051 \leq n \leq 10^51≤n≤105 * 1≤ai,bi≤n1 \leq a_i, b_i \leq n1≤ai,bi≤n * 1≤ci≤1081 \leq c_i \leq 10^81≤ci≤108 * The number of test cases does not exceed 10.
输出描述:
For each test case, output an integer which denotes the result.
示例1
输入
复制
5 1 2 2 1 3 1 2 4 2 3 5 1 5 1 2 2 1 4 1 3 4 1 4 5 2
输出
复制
19 15
建立一棵最大生成树树B,其中每条边a,b的距离为现在的树A上的a,b点的最短距离。
明显能够想到树上各个点到A的直径上两个点其中之一是距离最大的。那么就选择点i和两个直径点之一的那条边就行。
#include<bits/stdc++.h>
using namespace std;
const int M = 100010;
struct fuck {
int v; long long d;
};
vector<fuck>G[M];
long long dis[M], udis[M];
long long maxn = -1;int pos = 0;
void dfs(int x,int fa,long long dis[]) {
for (auto v : G[x]) {
if (v.v == fa)continue;
dis[v.v] = dis[x] + v.d;
if (dis[v.v] > maxn) {
maxn = dis[v.v];
pos = v.v;
}
dfs(v.v, x, dis);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;
while (cin >> n) {
for (int i = 0; i <= n; i++)
G[i].clear();
for (int i = 1; i < n; i++) {
int a, b; long long c;
cin >> a >> b >> c;
G[a].push_back(fuck{ b,c }); G[b].push_back(fuck{ a,c });
}
if (n == 1) {
cout << 0 << "\n";
continue;
}
for (int i = 0; i <= n; i++)
dis[i] = -1;
dis[1] = 0;
maxn = -1, pos = 0;
dfs(1, 0, dis);
int zj1 = pos;
for (int i = 0; i <= n; i++)
dis[i] = -1;
dis[zj1] = 0;
maxn = -1, pos = 0;
dfs(zj1, 0, dis);
int zj2 = pos;
for (int i = 0; i <= n; i++)
udis[i] = -1;
udis[zj2] = 0;
maxn = -1, pos = 0;
dfs(zj2, 0, udis);
long long res = dis[zj2];
for (int i = 1; i <= n; i++) {
if (i == zj1 || i == zj2)continue;
res += max(dis[i], udis[i]);
}
cout << res << "\n";
}
return 0;
}