TZOJ 3481 Highway Construction(树的直径+最短路)

博客围绕在城市连通图中建造高速的问题展开。给定城市社区及道路距离,需建一条高速使任一社区到最近高速入口的最长距离最小。通过将问题转化为树结构,求出树的直径,答案是树直径上的点到其他点最短路的最大值,并给出输入输出示例。

描述

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?

输入

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-1lines 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 each city map, output on a single line the farthest distance from any community to the nearest on-ramp of the new highway.

样例输入

6
2 1 10
3 1 15
1 4 5
4 5 12
4 6 8
0

样例输出

10

题意

给你一个连通图,让你造一条高速(高速必须建在路上,从A到B只有1条路),然后不在高速上的城市的邻近城市必须有高速,求出邻近城市到距离最近的有高速城市的最大距离

题解

邻近城市可以考虑树,求高速肯定是得树上的距离越长越好,可以求出树的直径

答案就是树的直径上的点到所有其他的最短路取最大值

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3   
 4 const int maxn=1e5+5;
 5 
 6 vector< pair<int,int> >G[maxn];
 7 
 8 int d[maxn],pre[maxn];
 9 int maxx,mpos;
10 bool vis[maxn];
11 
12 void dfs(int u)
13 {
14     for(int i=0;i<(int)G[u].size();i++)
15     {
16         int v=G[u][i].first;
17         int w=G[u][i].second;
18         if(!vis[v])
19         {
20             d[v]=d[u]+w;
21             if(d[v]>maxx)
22             {
23                 maxx=d[v];
24                 mpos=v;
25             }
26             pre[v]=u;
27             vis[v]=true;
28             dfs(v);
29         }
30             
31     }
32 }
33 
34 int main()
35 {
36     int n;
37     while(scanf("%d",&n)!=EOF,n)
38     {
39         for(int i=1;i<=n;i++)d[i]=0x3f3f3f3f,vis[i]=false,G[i].clear();
40         for(int i=1,u,v,w;i<n;i++)
41         {
42             scanf("%d%d%d",&u,&v,&w);
43             G[u].push_back(make_pair(v,w));
44             G[v].push_back(make_pair(u,w));
45         }
46         d[1]=0,vis[1]=true,maxx=0;
47         dfs(1);
48         for(int i=1;i<=n;i++)pre[i]=-1,d[i]=0x3f3f3f3f,vis[i]=false;
49         d[mpos]=0,vis[mpos]=true,maxx=0;
50         dfs(mpos);
51         queue<int>q;
52         for(int i=1;i<=n;i++)d[i]=0x3f3f3f3f;
53         for(int i=mpos;i!=-1;i=pre[i])
54         {
55             q.push(i);
56             d[i]=0;
57         }
58         while(!q.empty())
59         {
60             int u=q.front();q.pop();
61             for(int i=0;i<(int)G[u].size();i++)
62             {
63                 int v=G[u][i].first;
64                 int w=G[u][i].second;
65                 if(d[v]>d[u]+w)
66                 {
67                     d[v]=d[u]+w;
68                     q.push(v);
69                 }
70             }
71         }
72         printf("%d\n",*max_element(d+1,d+1+n));
73     }
74     return 0;
75 }

转载于:https://www.cnblogs.com/taozi1115402474/p/9551477.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值