H. Highway
In ICPCCamp there were n towns conveniently numbered with 1,2,...,n connected with (n−1) roads. The
i-th road connecting towns a i and b i has length c i . 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) cents, where δ(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.
Input
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 a i , b i and
c i .
• 1 ≤ n ≤ 10 5
• 1 ≤ a i ,b i ≤ n
• 1 ≤ c i ≤ 10 8
• The number of test cases does not exceed 10.
Output
For each test case, output an integer which denotes the result.
Sample Input
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
Sample Output
19
15
官方题解:
先求出树的最远点对(树的直径)d1,d2,再求出以直径的两个端点为起点的dist[i](起点到i的距离),首先将直径(d1,d2的距离)加入集合,对于其他点i,加入max(d1到i的距离,d2到i的距离)到集合,集合所构成的树就是题目的答案
至于树的最远点对怎么求就懒得说了
#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<cmath> #include<set> #include<stack> #define ll long long #define max(x,y) (x)>(y)?(x):(y) #define min(x,y) (x)>(y)?(y):(x) #define cls(name,x) memset(name,x,sizeof(name)) using namespace std; const int inf=1<<28; const int maxn=100010; const int maxm=110; const int mod=1e9+7; const double pi=acos(-1.0); int n; struct node { int next,to,cost; }edge[maxn*2]; int head[maxn],cnt; void add(int st,int ed,int cost) { edge[cnt].to=ed; edge[cnt].cost=cost; edge[cnt].next=head[st]; head[st]=cnt++; } ll distd1[maxn],distd2[maxn]; int vis[maxn]; void dfs(int x,ll d,ll dist[]) { vis[x]=1; dist[x]=d; for(int i=head[x];i!=-1;i=edge[i].next) { if(vis[edge[i].to]==0) dfs(edge[i].to,d+edge[i].cost,dist); } } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d",&n)) { cls(head,-1); cnt=0; for(int i=0;i<n-1;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); add(a,b,c); add(b,a,c); } cls(vis,0); dfs(1,0,distd1); int d1,d2; ll maxdist=0; for(int i=1;i<=n;i++) if(distd1[i]>maxdist) maxdist=distd1[i],d1=i; cls(vis,0); dfs(d1,0,distd1); maxdist=0; for(int i=1;i<=n;i++) if(distd1[i]>maxdist) maxdist=distd1[i],d2=i; cls(vis,0); dfs(d2,0,distd2); ll ans=distd1[d2]; for(int i=1;i<=n;i++) { if(i!=d1&&i!=d2) ans+=max(distd1[i],distd2[i]); } printf("%I64d ",ans); } return 0; }