列表

详情


NC20455. [TJOI2017]城市

描述

从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作。这个地区一共有ri座城市,《-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达,但是通过一条高速公路需要收取一定的交通费用。小明对这个地区深入研究后,觉得这个地区的交通费用太贵。小明想彻底改造这个地区,但是由于上司给他的资源有限,因而小明现在只能对一条高速公路进行改造,改造的方式就是去掉一条高速公路,并且重新修建一条一样的高速公路(即交通费用一样),使得这个地区的两个城市之间的最大交通费用最小(即使得交通费用最大的两座城市之间的交通费用最小),并且保证修建完之后任意两座城市相互可达。如果你是小明,你怎么解决这个问题?

输入描述

输入数据的第一行为一个整数n,代表城市个数。
接下来的n - 1行分别代表了最初的n-1条公路情况。每一行都有三个整数u,v,d。u,v代表这条公路的两端城市标号,d代表这条公路的交通费用。
1 <= u,v <= n,1<= d <= 2000

输出描述

输出数据仅有一行,一个整数,表示进行了最优的改造之后,该地区两城市之间最大交通费用。

示例1

输入:

5
1 2 1
2 3 2
3 4 3
4 5 4

输出:

7

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 1970ms, 内存消耗: 1384K, 提交时间: 2020-03-28 17:43:32

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+100;

int x[N],y[N],w[N];

vector<pair<int,int> >G[N]; 

int dp1[N],dp2[N];
int dis,res; 
void dfs1(int x,int fa)//直径 
{
	for(auto p:G[x])
	{
		int v=p.first,w=p.second;
		if(v==fa) continue;
		dfs1(v,x);
		if(dp1[x]<dp1[v]+w)
		{
			dp2[x]=dp1[x];
			dp1[x]=dp1[v]+w;
		}
		else if(dp2[x]<dp1[v]+w)dp2[x]=dp1[v]+w;
	}
	dis=max(dis,dp1[x]+dp2[x]);
}
void dfs2(int x,int fa,int ff)//算半径 
{
	res=min(res,max(ff,dp1[x]));
	for(auto p:G[x])
	{
		int v=p.first,w=p.second;
		if(v==fa) continue;
		if(dp1[x]==dp1[v]+w) dfs2(v,x,max(ff,dp2[x])+w);
		else dfs2(v,x,max(ff,dp1[x])+w);
	}
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		cin>>x[i]>>y[i]>>w[i];
		G[x[i]].push_back(make_pair(y[i],w[i]));
		G[y[i]].push_back(make_pair(x[i],w[i]));
	}
	int ans=1e9;
	for(int i=1;i<n;i++)
	{
		memset(dp1,0,sizeof dp1);
		memset(dp2,0,sizeof dp2);
		dis=0,res=1e9;
		int d1,d2,r1,r2;
		dfs1(x[i],y[i]); d1=dis;dis=0;
		dfs2(x[i],y[i],0);r1=res;res=1e9;
		dfs1(y[i],x[i]); d2=dis;
		dfs2(y[i],x[i],0);r2=res;
		ans=min(ans,max(d1,max(d2,r1+r2+w[i])));
	}
	cout<<ans<<endl;
	return 0;
} 

上一题