您的位置:首页 > 其它

ccpc湘潭邀请赛 h-highway(树的直径)

2017-05-24 13:37 399 查看


Highway

Accepted : 141 Submit : 488
Time Limit : 4000 MS Memory Limit : 65536 KB 

Highway

In 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.


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 ai, bi and ci.

1≤n≤105
1≤ai,bi≤n
1≤ci≤108
The number of test cases does not exceed 10.


Output

For 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
;
ll disd1
,disd2
;
int first
;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐