Highway | ||
Accepted : 141 | Submit : 488 | |
Time Limit : 4000 MS | Memory Limit : 65536 KB |
HighwayIn ICPCCamp there were n towns conveniently numbered with 1,2,…,n connected with (n−1) roads. The i -th road connecting towns ai and bi has length ci . 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. InputThe 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 ai , bi and ci .
OutputFor each test case, output an integer which denotes the result. |
题目链接:http://202.197.224.59/OnlineJudge2/index.php/Contest/read_problem/cid/43/pid/1267
说实话,当时没读懂这题的意思,对于树的直径这个概念也是一无所知
官方题解:
关于树的直径
树的直径是指树上权值和最大的路径(最简单路径,即每一个点只经过一次,也就是最大生成树)
存在结论:对于树上的任意一个节点,距离这个节点最远的距离一定是到直径的端点的距离;
由于只有(n-1)条边,直接dfs找最大生成树即可
先从任意一个点dfs找出距离其最远的点d1,则d1一定为树的直径的一个端点;
然后由d1出发找到距离其最远的点d2,则d2为树的直径的另一个端点,保存路径上所有点到d1的距离,最后会用到;
最后由d2向的搜索,保存路径上所有点到d2的距离;
由于d1到d2一定为最远,直接加上,其他点加上max(到d1距离,到d2距离),即可求出最大花费;
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define wtf printf("wtf\n");
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define N 100010
#define ll long long
using namespace std;
int n,len;
bool vis[N];
ll disd1[N],disd2[N];
int first[N];
struct node
{
int to,nex;
ll w;
}e[N<<1];
void dfs(int st,ll len,ll dis[])
{
vis[st]=true;
dis[st]=len;
for(int i=first[st];~i; i=e[i].nex)
{
if(!vis[e[i].to])
{
dfs(e[i].to,len+e[i].w,dis);
}
}
}
void add_edge(int u,int v,ll w)
{
e[len].to=v;
e[len].w=w;
e[len].nex=first[u];
first[u]=len++;
}
int main()
{
while(~scanf("%d",&n))
{
int u,v,w;
len=0;
mem(disd1,0);
mem(disd2,0);
mem(first,-1);
for(int i=1; i<n; i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
mem(vis,false);
ll maxx=0;
dfs(1,0,disd1);
int d1,d2;
for(int i=1; i<=n; i++)
{
if(maxx<disd1[i])
{
maxx=disd1[i];
d1=i;
}
}
mem(vis,false);
dfs(d1,0,disd1);
maxx=0;
for(int i=1; i<=n; i++)
{
if(maxx<disd1[i])
{
maxx=disd1[i];
d2=i;
}
}
mem(vis,false);
dfs(d2,0,disd2);
ll ans=disd1[d2];
for(int i=1;i<=n;i++)
{
if(i!=d1&&i!=d2)
{
ans+=max(disd1[i],disd2[i]);
}
}
printf("%I64d\n",ans);
}
}
参考博客: Alzh