ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[Tjoi2017]城市

2019-10-27 19:56:44  阅读:240  来源: 互联网

标签:小明 费用 地区 城市 高速公路 Tjoi2017 交通


从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作。这个地区一共有ri座城市,《-1条高速公
路,保证了任意两运城市之间都可以通过高速公路相互可达,但是通过一条高速公路需要收取一定的交通费用。小
明对这个地区深入研究后,觉得这个地区的交通费用太贵。小明想彻底改造这个地区,但是由于上司给他的资源有
限,因而小明现在只能对一条高速公路进行改造,改造的方式就是去掉一条高速公路,并且重新修建一条一样的高
速公路(即交通费用一样),使得这个地区的两个城市之间的最大交通费用最小(即使得交通费用最大的两座城市
之间的交通费用最小),并且保证修建完之后任意两座城市相互可达。如果你是小明,你怎么解决这个问题?
Input
输入数据的第一行为一个整数n,代表城市个数。
接下来的n - 1行分别代表了最初的n-1条公路情况。
每一行都有三个整数u,v,d。u,v代表这条公路的两端城市标号,d代表这条公路的交通费用。
1<=n<=5000
1 <= u,v <= n,1<= d <= 2000
Output
输出数据仅有一行,一个整数,表示进行了最优的改造之后,该地区两城市 之间最大交通费用。
Sample Input
5
1 2 1
2 3 2
3 4 3
4 5 4
Sample Output
7

/*
此题同ioi2013 dreaming那个题
枚举下删除的哪一条边,于是整个树变成两个连通块
对于连通块找出其半径,半径就是树中每个点的最长链的最小值
因为是希望找出新树的直径尽可能小嘛!
于是新树的直径可以是原来两个树的直径之一,可是用某条边连接其半径所形成 
*/ 
#include<bits/stdc++.h>
#define N 5007
#define inf 0x3f3f3f3f
using namespace std;
int n,m,ans,cnt,dis,res;
int head[N<<1],mv[N],u[N],v[N],w[N];
int dp[N][2];
bool vis[N];
struct edge
{
    int u,v,w,nxt;
}e[N<<1];

inline void add(int u,int v,int w)
{
    e[++cnt].v=v;
	e[cnt].w=w;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void getd(int u)
{
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if(vis[v]) continue;
        vis[v]=1;
		getd(v);
        if(dp[u][0]<dp[v][0]+e[i].w)
        {
            dp[u][1]=dp[u][0];mv[u]=v;
            dp[u][0]=dp[v][0]+e[i].w;
        }
        else if(dp[u][1]<dp[v][0]+e[i].w)
            dp[u][1]=dp[v][0]+e[i].w;
    }
	dis=max(dis,dp[u][0]+dp[u][1]);
}

void getr(int u,int from)
{
    res=min(res,max(from,dp[u][0]));
    //半径为每个点的最长链中的最小值 
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if(!vis[v]) continue;
        vis[v]=0;
        if(mv[u]==v) 
          getr(v,max(dp[u][1]+e[i].w,from+e[i].w));
        else 
          getr(v,max(dp[u][0]+e[i].w,from+e[i].w));
        
    }
}

void clear()
{
    memset(dp,0,sizeof dp);
    memset(mv,0,sizeof mv);
    memset(vis,0,sizeof vis);
    res=inf;dis=0;
}

int main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        u[i]=read();v[i]=read();w[i]=read();
        add(u[i],v[i],w[i]);add(v[i],u[i],w[i]);
    }
    int d1,d2,r1,r2;ans=res=inf;dis=0;
    for(int i=1;i<n;i++) //枚举删除哪一条边 
    {
        vis[v[i]]=1;//设第i条边被删除,设右端点已走过 
		getd(u[i]); //从左端点开始,求这个连通块的直径 
		d1=dis;
        dis=0;
		getd(v[i]); 
		d2=dis;
      
        vis[v[i]]=0;
		getr(u[i],0); 
		r1=res;
        res=inf;
		getr(v[i],0); 
		r2=res;
        //联通块1,2的半径 
        ans=min(ans,max(max(d1,d2),r1+r2+w[i]));
        //新树直径可能是原来两个树的直径,或用w[i]连接两个树的半径形成,取其最大值 
        clear();
    }
    printf("%d\n",ans);
    return 0;
}

  

 

标签:小明,费用,地区,城市,高速公路,Tjoi2017,交通
来源: https://www.cnblogs.com/cutemush/p/11748671.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有