显然删掉的边肯定是直径上的边。考虑枚举删哪一条。然后考虑怎么连。显然新边应该满足其两端点在各自树中作为根能使树深度最小。只要线性求出这个东西就可以了,这与求树的重心的过程类似。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 5010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,p[N],deep[N],fa[N],f[N],len[N],t,root,ans=N*N;
bool flag[N];
struct data{int to,nxt,len;
}edge[N<<];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k])
{
deep[edge[i].to]=deep[k]+edge[i].len;
fa[edge[i].to]=k;
len[edge[i].to]=edge[i].len;
dfs(edge[i].to);
}
}
int dp(int k,int ban)
{
flag[k]=;
int mx=,mx2=,ans=;
for (int i=p[k];i;i=edge[i].nxt)
if (!flag[edge[i].to]&&edge[i].to!=ban)
{
ans=max(ans,dp(edge[i].to,ban));
int x=f[edge[i].to]+edge[i].len;
if (x>mx) mx2=mx,mx=x;
else if (x>mx2) mx2=x;
}
f[k]=mx;
return max(ans,mx+mx2);
}
int findroot(int k,int ban,int last)
{
int mx=,mx2=,l=,len=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k]&&edge[i].to!=ban)
{
int x=f[edge[i].to]+edge[i].len;
if (x>mx) mx2=mx,mx=x,l=edge[i].to,len=edge[i].len;
else if (x>mx2) mx2=x;
}
if (max(last,mx2)+len<mx) return findroot(l,ban,max(last,mx2)+len);
else return k;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4890.in","r",stdin);
freopen("bzoj4890.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<n;i++)
{
int x=read(),y=read(),z=read();
addedge(x,y,z),addedge(y,x,z);
}
dfs();
int root=;for (int i=;i<=n;i++) if (deep[i]>deep[root]) root=i;
fa[root]=deep[root]=;dfs(root);
int x=;for (int i=;i<=n;i++) if (deep[i]>deep[x]) x=i;
while (x!=root)
{
memset(f,,sizeof(f));
memset(flag,,sizeof(flag));
int t=max(dp(root,x),dp(x,fa[x]));
int u=findroot(root,x,),v=findroot(x,fa[x],);
memset(f,,sizeof(f));
memset(flag,,sizeof(flag));
dp(u,x),dp(v,fa[x]);
ans=min(ans,max(f[u]+f[v]+len[x],t));
x=fa[x];
}
cout<<ans;
return ;
}

BZOJ4890 Tjoi2017城市的更多相关文章

  1. bzoj4890[Tjoi2017]城市(树的半径)

    4890: [Tjoi2017]城市 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 149  Solved: 91[Submit][Status][D ...

  2. [BZOJ4890][TJOI2017]城市(DP)

    题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达,但是通过一条高速公路需要收 ...

  3. BZOJ4890 [Tjoi2017]城市 【树形dp】

    题目链接 BZOJ4890 题解 枚举断开哪一条边,然后对剩余的两棵树分别做一遍换根法树形dp 需要求出每个点到树中其它点距离的最大值\(f[i]\)和次大值\(g[i]\)[用以辅助换根计算最大值] ...

  4. 【BZOJ4890】[TJOI2017]城市(动态规划)

    [BZOJ4890][TJOI2017]城市(动态规划) 题面 BZOJ 洛谷 题解 数据范围都这样了,显然可以暴力枚举断开哪条边. 然后求出两侧直径,暴力在直径上面找到一个点,使得其距离直径两端点的 ...

  5. [洛谷P3761] [TJOI2017]城市

    洛谷题目链接:[TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速 ...

  6. 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市

    P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...

  7. [TJOI2017]城市(树的直径)

    [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达, ...

  8. BZOJ4890 & 洛谷3761:[TJOI2017]城市——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4890 https://www.luogu.org/problemnew/show/P3761 从加 ...

  9. [TJOI2017]城市 【树的直径+暴力+优化】

    Online Judge:Luogu P3761 Label:树的直径,暴力 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有n座城市,n-1条高速公路,保证了 ...

随机推荐

  1. WPF 日历模板改写

    原文:WPF 日历模板改写 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/details/83346221  本 ...

  2. easyui -validatebox 验证框加载

    问题: easyui验证狂框有时会验证输入字符的位数,或者验证有效字符组合 解决: 使用easyui的验证框,继承验证框,指定输入框为验证框即可 $(function(){ $.extend($.fn ...

  3. [POI2011]MET-Meteors

    题面 题解 首先我们尝试暴力,那么就对每个点二分一下即可. 我们发现单独二分复杂度太高,而且有些地方很浪费,如求前缀和等. 那么我们就想,能否将它们合并在一起二分呢? 于是就有了整体二分 整体二分即可 ...

  4. L015-linux系统文件权限体系手把手详解小结

    L015-linux系统文件权限体系手把手详解小结 2016-5-24 今天星期二,昨天和今天利用一些闲散时间把第15节课学完了,最近有点懒散哈,还得努力才是.. 这节课内容不多,扩展的也少,主要就是 ...

  5. 基于ejabberd实现各个客户端消息同步

    先上图再说(左侧是web端,右侧是ios端)              要实现上面的功能,如果所有设备都在线的话,那么carboncopy(xmpp xep-0280协议)这个模块是可以实现接收到的消 ...

  6. IL指令

    这是网上搜集到的il指令修改时可作为参考 名称说明Add将两个值相加并将结果推送到计算堆栈上.Add.Ovf将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上.Add.Ovf.Un将两个无符号整 ...

  7. python全栈开发-面向对象-初识2

    python_17_day 今日主要内容: 1.类空间,对象空间,查询顺序. 2.组合. 1.类空间,对象空间,查询顺序. class Person: animal = '高级动物' soul = ' ...

  8. 接口自动化之接口工具选取(jmeter)

    jmeter进行接口测试,网上简易教程很多 其实关于HTTP接口测试的实现,网上还有很多其他工具诸如:http在线请求测试/谷歌插件postman/火狐插件等. 至于选择jmeter的原因,其实没有原 ...

  9. 关于scrum敏捷测试

    关于scrum的一些定义 敏捷软件开发方法是一种把新增功能通过较小的循环逐步迭代添加到项目中(的项目管理方法),工作是由自我组织的团队以高效合作的方式拥抱和适应变化来保证客户需求被真正满足的方式来完成 ...

  10. python简介、第一个python程序、变量、字符编码、用户交互程序、if...else、while、for

    也愿大家永葆初心-- 已识乾坤大,犹怜草木青. 一.python简介 首先,我们普及一下编程语言的基础知识.用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个MP3,编写一个文档等等,而计算 ...