博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ4890][TJOI2017]城市(DP)
阅读量:4477 次
发布时间:2019-06-08

本文共 2054 字,大约阅读时间需要 6 分钟。

 

题目描述

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

输入输出格式

输入格式:

 

输入数据的第一行为一个整数n,代表城市个数。

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

1 <= u,v <= n,1<= d <= 2000

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 
51 2 12 3 23 4 34 5 4
输出样例#1: 
7

说明

对于30%的数据,1<=n<500

对于100%的数据,1<=n<=5000

枚举选择哪条边将它切断,然后对分成的两棵树分别求树内最长链和到以某结点为端点的最长链的最小值,更新答案。

显然这条边一定在树的直径上,如果加入此优化可以快十多倍。

1 #include
2 #include
3 #define rep(i,l,r) for (register int i=l; i<=r; i++) 4 #define For(i,x) for (register int i=h[x],k; i; i=nxt[i]) 5 using namespace std; 6 7 const int N=100100,inf=1000000000; 8 int n,u,v,w,cnt,mn,mn1,tmp,ans,to[N],h[N],val[N],nxt[N],mx1[N],mx2[N],pre[N]; 9 void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }10 11 void dfs(int x,int fa){12 mx1[x]=mx2[x]=pre[x]=0;13 For(i,x) if ((k=to[i])!=fa){14 dfs(k,x); int t=mx1[k]+val[i];15 if (t>mx1[x]) mx2[x]=mx1[x],mx1[x]=t,pre[x]=k;16 else if (t>mx2[x]) mx2[x]=t;17 tmp=max(tmp,mx1[x]+mx2[x]);18 }19 }20 21 void dfs2(int x,int fa){22 mn=min(mn,mx1[x]);23 For(i,x) if ((k=to[i])!=fa){24 int t=(pre[x]==k) ? mx2[x]+val[i] : mx1[x]+val[i];25 if (t>mx1[k]) mx2[k]=mx1[k],mx1[k]=t,pre[k]=x;26 else if (t>mx2[k]) mx2[k]=t;27 dfs2(k,x);28 }29 }30 31 int main(){32 scanf("%d",&n); ans=inf;33 rep(i,1,n-1) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);34 rep(i,1,n-1){35 u=to[i*2-1]; v=to[i*2]; w=val[i*2]; tmp=0;36 dfs(v,u); mn=inf; dfs2(v,u); mn1=mn;37 dfs(u,v); mn=inf; dfs2(u,v);38 ans=min(ans,max(tmp,mn+mn1+w));39 }40 printf("%d\n",ans);41 return 0;42 }

 

转载于:https://www.cnblogs.com/HocRiser/p/8457611.html

你可能感兴趣的文章
IIS的配置
查看>>
音乐播放器的实现
查看>>
第十四周 11.29-12.5
查看>>
synchrozied方法和synchrozied修饰代码块的区别
查看>>
bootstrap 中的 iCheck 全选反选功能的实现
查看>>
冲刺周—The First Day
查看>>
C#中多线程的并行处理
查看>>
FluentScheduler定时器
查看>>
数字证书原理 - 转自 http://www.cnblogs.com/JeffreySun/archive/2010/06/24/1627247.html
查看>>
Android应用程序的组成部分
查看>>
Git报错Unable to create 'XXX/.git/index.lock': File exists
查看>>
查找文件并执行的shell命令
查看>>
7.01-beautiful_soup2
查看>>
在Windows上弄一个redis的docker容器
查看>>
Servlet组件之一——Filter过滤器
查看>>
Java 三大特性——封装、继承、多态
查看>>
软件测试基础 - 配置管理
查看>>
数据仓库创建以及开发人员操作的基本命令
查看>>
【翻译】Ext JS最新技巧——2014-5-12
查看>>
关于float和margin
查看>>