Hrbust 1460 Highway Construction【树的直径】

224 篇文章 2 订阅

Highway Construction
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 23(10 users)Total Accepted: 9(9 users)Rating: Special Judge: No
Description

As head of the Accessible Commuting Movement (ACM), you've been lobbying the mayor to build a new highway in your city. Today is your lucky day, because your request was approved. There is one condition though: You must provide the plan for the best highway artery to construct, or else it's not going to happen!


You have a map that shows all communities in your city, each with a unique number, where you may place highway on-ramps. On the map are a set of roadways between pairs of communities, labelled with driving distances, which you may choose to replace with your highway line. Using this network of roadways, there is exactly one route from any one community to another. In other words, there are no two different sets of roadways that would lead you from community A to community B.




You can build a single highway that runs back and forth between any two communities of your choosing. It will replace the unique set of roadways between those two communities, and an on-ramp will be built at every community along the way. Of course, residents of communities that will not have an on-ramp will have to drive to the nearest one that does in order to access your new highway. 


You know that long commutes are very undesirable, so you are going to build the highway so that longest drive from any community to the nearest on-ramp is minimized. Given a map of your city with the roadways and driving distances, what is the farthest distance from any community that someone would have to drive to get to the nearest on-ramp once your new highway is complete?

Input

The input consists of multiple test cases. Each test case is a description of a city map, and begins with a single line containing an integer N (2 <= N <= 100,000), the number of communities in the city. Then N - 1 lines follow, each containing three integers, i; j (1 <= i; j <= n), and d (1 <= d <= 10,000). Each line indicates that communities i and j are connected by a roadway with driving distance d. Input is followed by a single line with N = 0, which should not be processed. 

For example:

6

2 1 10

3 1 15

1 4 5

4 5 12

4 6 8

0

Output

For each city map, output on a single line the farthest distance from any community to the nearest on-ramp of the new highway. 

For example:

10

Sample Input

6

2 1 10

3 1 15

1 4 5

4 5 12

4 6 8

0

Sample Output
10
Source
2010 Stanford Local ACM Programming Contest

题目大意:


求树的直径外的其他点到树的直径的最长路径。


思路:


①两次Dfs出树的直径的路径,将每个点都标记出来,然后将这一条路上的所有边都删掉。


②然后再从每一个树的直径上的点出发,Dfs一次,求出最终Ans即可。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<pair<int,int>,int>s;
struct node
{
    int from;
    int to;
    int w;
    int next;
}e[1500000];
int n,cont,maxn,root;
int head[150000];
int fa[150000];
void add(int from,int to,int w)
{
    e[cont].to=to;
    e[cont].w=w;
    e[cont].next=head[from];
    head[from]=cont++;
}
void Dfs(int u,int from,int len)
{
    if(len>maxn)root=u,maxn=len;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        int w=e[i].w;
        if(v==from)continue;
        Dfs(v,u,len+w);
    }
}
void dfs(int u,int from,int len)
{
    fa[u]=from;
    if(len>maxn)maxn=len,root=u;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        int w=e[i].w;
        if(v==from)continue;
        dfs(v,u,len+w);
    }
}
void Slove(int u,int from,int len)
{
    if(len>maxn)maxn=len;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        int w=e[i].w;
        if(v==from)continue;
        if(s[make_pair(u,v)]==1)continue;
        Slove(v,u,len+w);
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        s.clear();
        if(n==0)break;
        cont=0;
        memset(head,-1,sizeof(head));
        for(int i=0;i<n-1;i++)
        {
            int x,y,w;scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);add(y,x,w);
        }
        maxn=0;
        Dfs(1,-1,0);
        int pre=root;
        maxn=0;
        dfs(root,-1,0);
        int tmp=root;
        while(root!=pre)
        {
            int f=fa[root];
            s[make_pair(f,root)]=1;
            s[make_pair(root,f)]=1;
            root=f;
        }
        maxn=0;
        root=tmp;
        while(root!=pre)
        {
            Slove(root,-1,0);
            int f=fa[root];
            root=f;
        }
        printf("%d\n",maxn);
    }
}

















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值