链接:https://ac.nowcoder.com/acm/contest/1109/H
来源:2019牛客国庆集训派对day4
证明:https://blog.csdn.net/qq_42217376/article/details/102148990
- 题目描述
- 输入描述:
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 ≤ 1 0 5 1≤ n ≤10^{5} 1≤n≤105
1 ≤ a i , b i ≤ n 1≤a_{i},b_{i}≤n 1≤ai,bi≤n
1 ≤ c i ≤ 1 0 8 1≤c_{i}≤10^{8} 1≤ci≤108
The number of test cases does not exceed 10.- 输出描述:
For each test case, output an integer which denotes the result.- 输入
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
n
n 个城镇被
n
−
1
n-1
n−1 条路连接,现在
B
o
b
o
Bobo
Bobo 想要花钱建
n
−
1
n-1
n−1 条铁路使得每个城镇都联通,并且任意两个城镇之间只有一条路径。求出
B
o
b
o
Bobo
Bobo 的最大花费。
思路:我们先找到给出的树的树的直径,那么树的直径上的两个端点一定是最远的,对于其他的点我们取到这两个端点最远的一条路径即可。最后计算所有端点到这个端点的最大值相加,注意这里多加了一个树的直径,减去一个直径即为最终答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max_n=1e5+10;
int head[Max_n],cnt,mmaxdot,n;
ll dis[Max_n],ans,disdot1[Max_n],disdot2[Max_n];
bool vis[Max_n];
struct Edge{
int u,v,w,next;
}edge[Max_n<<1];
void addedge(int u,int v,int w){
edge[cnt].u=u; edge[cnt].v=v;
edge[cnt].w=w; edge[cnt].next=head[u];
head[u]=cnt++;
}
void bfs(int s){
memset(vis,false,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<int>q; ans=0; mmaxdot=0;
q.push(s); vis[s]=true;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(!vis[v]){
if(dis[v]<dis[u]+(ll)edge[i].w){
dis[v]=dis[u]+(ll)edge[i].w;
vis[v]=true;
q.push(v);
}
}
}
}
for(int i=1;i<=n;i++){
if(ans<dis[i]){
ans=dis[i]; mmaxdot=i;
}
}
}
int main(){
while(~scanf("%d",&n)){ cnt=0;
for(int i=1;i<=n;i++){ head[i]=-1,disdot1[i]=0,disdot2[i]=0; }
for(int i=1;i<=n-1;i++){
int u,v,w; scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w); addedge(v,u,w);
}
bfs(1); bfs(mmaxdot);
//for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
//cout<<endl<<mmaxdot<<endl;
for(int i=1;i<=n;i++) disdot1[i]=dis[i];
bfs(mmaxdot); ll Max=ans;
//for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
//cout<<endl<<mmaxdot<<endl;
for(int i=1;i<=n;i++) disdot2[i]=dis[i];
ll res=0;
for(int i=1;i<=n;i++) res+=max(disdot1[i],disdot2[i]);
printf("%lld\n",res-Max);
}
return 0;
}
/**
* Copyright(c)
* All rights reserved.
* Author : Max_n
* Date : 2019-10-05-15.56.59
* Description : 树的直径 - bfs
*/