题目描述
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
题意:给定n个点(1~n-1),并给定n-1条路径,求使所有点联通的最大花费
思路:遍历所有点找到每个点距离最远的点中间的路径长度累加即是答案,于是就转化为了求树的直径的问题,对于每个点都求一遍直径即可得到答案
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define int long long
const int N=100010,M=2*N;
int n;
int h[N],ne[M],e[M],w[M],idx;
int dist[N],dist1[N];
bool st[N];
void add(int a,int b,int c)
{
w[idx]=c,e[idx]=b,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])
{
dist[j]=dist[u]+w[i];
dfs(j);
}
}
}
void dfs1(int u)
{
st[u]=1;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(!st[j])
{
dist1[j]=dist1[u]+w[i];
dfs1(j);
}
}
}
signed main()
{
while(cin>>n)
{
idx=0;
memset(h,-1,sizeof h);
memset(dist,0,sizeof dist);
memset(dist1,0,sizeof dist1);
memset(st,0,sizeof st);
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
dfs(1);
int len=-1,start=0;
for(int i=1;i<=n;i++)
if(dist[i]>len)
{
len=dist[i];
start=i;
}
memset(st,0,sizeof st);
dfs1(start);
len=-1;
for(int i=1;i<=n;i++)
if(dist1[i]>len)
{
len=dist1[i];
start=i;
}
memset(st,0,sizeof st);
memset(dist,0,sizeof dist);
dfs(start);
int res=0;
for(int i=1;i<=n;i++)
res+=max(dist[i],dist1[i]);
res-=len;
printf("%lld\n",res);
}
}