【Luogu】P3761城市(dfs)
emmm我思维好水……
想了一会lct发现好像不对,然后开始转DP稍微有一点思路,然后看了题解……
首先可以枚举边,然后原树被你拆成了两个子树。
设D1D2是两个子树的直径,W1W2是子树内某个点到其他点最长距离的最小值,val是断掉的边的权值
然后呢我们发现此时的答案成为了max(max(D1,D2),W1+W2+val)
然后可以发现W1W2可以通过枚举子树直径上的点求得。
然后这样就TLE了23333
一个大优化是我们可以发现枚举断掉哪条边这个步骤可以变成枚举断掉直径上哪条边,只有这样才能对答案产生影响
然后就快了九倍……
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#define maxn 6000
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int n; struct Edge{
int next,to,val;
}edge[maxn*];
int head[maxn],num;
inline void add(int from,int to,int val){
edge[++num]=(Edge){head[from],to,val};
head[from]=num;
} int dis[maxn];
bool vis[maxn]; void find(int x,int fa,int lim){
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa||to==lim) continue;
dis[to]=dis[x]+edge[i].val;
find(to,x,lim);
}
return;
} void record(int x,int fa,int goal){
if(x==goal){
vis[x]=;
return;
}
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
record(to,x,goal);
if(vis[to]) vis[x]=;
}
return;
} struct ANSWER{
int x,y;
}; ANSWER ask(int x,int fa){
memset(vis,,sizeof(vis));
memset(dis,-,sizeof(dis));
dis[x]=;
find(x,fa,fa);
int now=;
for(int i=;i<=n;++i)
if(dis[i]>dis[now]) now=i;
dis[now]=;
find(now,now,fa);
int to=;
for(int i=;i<=n;++i)
if(dis[i]>dis[to]) to=i;
record(now,now,to);
ANSWER ans=(ANSWER){dis[to],0x7fffffff};
for(int i=;i<=n;++i)
if(vis[i]) ans.y=min(ans.y,max(dis[to]-dis[i],dis[i]));
return ans;
} bool vie[maxn*]; int main(){
n=read();
for(int i=;i<n;++i){
int from=read(),to=read(),val=read();
add(from,to,val);
add(to,from,val);
}
ask(,);
for(int i=;i<=num;i+=){
if(vis[edge[i].to]==||vis[edge[i+].to]==) continue;
vie[i]=;
}
int ans=0x7fffffff;
for(int i=;i<=num;i+=){
if(vie[i]==) continue;
int from=edge[i].to,to=edge[i+].to,val=edge[i].val;
ANSWER l1=ask(from,to); ANSWER l2=ask(to,from);
// printf("%d %d %d %d %d %d %d\n",from,to,val,l1.x,l1.y,l2.x,l2.y);
ans=min(ans,max(max(l1.x,l2.x),l1.y+l2.y+val));
}
printf("%d\n",ans);
return ;
}
【Luogu】P3761城市(dfs)的更多相关文章
- luogu P1401 城市
题目链接 luogu P1401 城市 题解 二分最小边权,dinic检验 代码 // luogu-judger-enable-o2 /* 二分最小边权,dinic检验 */ #include< ...
- luogu P3761 [TJOI2017]城市 树的直径 bfs
LINK:城市 谢邀,学弟说的一道毒瘤题. 没有真正的省选题目毒瘤 或者说 写O(n)的做法确实毒瘤. 这里给一个花20min就写完的非常好写的暴力. 容易想到枚举哪条边删掉 删掉之后考虑在哪两个点上 ...
- luogu P4842 城市旅行
嘟嘟嘟 好题,好题 刚开始突发奇想写了一个\(O(n ^ 2)\)暴力,结果竟然过了?!后来才知道是上传题的人把单个数据点开成了10s-- 不过不得不说我这暴力写的挺好看的.删边模仿链表删边,加边的时 ...
- [luogu]P1041 传染病控制[dfs]
[luogu]P1041 传染病控制 ——!x^n+y^n=z^n 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的 ...
- Luogu P1401 城市(二分+网络流)
P1401 城市 题意 题目描述 N(2<=n<=200)个城市,M(1<=m<=40000)条无向边,你要找T(1<=T<=200)条从城市1到城市N的路,使得最 ...
- luogu P1453 城市环路
题目描述 整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路.保证环上任意两点有且只有2条路径互通.图中的其它部分皆隶属城市郊区. 现在,有一位名叫Jim的同学想在B市开 ...
- LUOGU P1453 城市环路(基环树+dp)
传送门 解题思路 一道基环树上$dp$的题,这种题比较套路吧,首先第一遍$dfs$把环找出来,然后对于环上的每一个点都向它子树内做一次树形$dp$,$f[i][0/1]$表示到了$i$这个点选或不选的 ...
- luogu P1784 数独 dfs 舞蹈链 DXL
LINK:数独 这道题好难 比DXL模板题要难上不少. 首先 还是考虑将行当做决策 那么 一共有\(9*9*9=729\) 个决策. 考虑列用来填充 需要有的条件为 某个位置能能放一次\(9*9\) ...
- [TJOI2017]城市 【树的直径+暴力+优化】
Online Judge:Luogu P3761 Label:树的直径,暴力 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有n座城市,n-1条高速公路,保证了 ...
随机推荐
- SAP Cloud for Customer客户主数据的重复检查-Levenshtein算法
SAP C4C的客户主数据创建时的重复检查,基于底层HANA数据库的模糊查找功能,根据扫描数据库中已有的数据检测出当前正在创建的客户主数据是否和数据库中记录有重复. 在系统里开启重复检查的配置: 在此 ...
- .net后台使用post方式对指定地址的方法传值并且获取结果的方法
/// <summary> /// .net 后台 post http地址请求 /// </summary> /// <param name="uri" ...
- JDK安装及环境变量配置详解
一.下载(Jdk 1.8 ) 1.下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151 ...
- 从屏幕截取一块区域,将其赋给imageView
UIGraphicsBeginImageContext(self.bounds.size); [self.layerrenderInContext:UIGraphicsGetCurrentContex ...
- 【转】MFC右键显示菜单之LoadMenu()
如何在界面内单击右键弹出自己设置的菜单选项? 步骤如下: 1.在资源MENU里添加一个菜单资源,命名为IDR_POP_MENU. 2.在自己添加的菜单中添加事件,如事件1,事件2,事件3,分别添加响应 ...
- 一些恶搞人的c++程序
top1: 不停打开的cmd(磁盘操作系统) 代码如下: #include<windows.h> using namespace std; int main() { system(&quo ...
- JDBC-防止SQL注入问题
String sql = "select * from user where name = '" + name + "' and password = '" ...
- 使用jmeter做简单的压测(检查点、负载设置、聚合报告)
1.添加断言(检查点) 在需要压测的接口下添加--断言--响应断言,取接口响应中包含有的数据即可 检查点HTTP请求-->断言-->响应断言1.名称.注释2.Apply to//作用于哪里 ...
- Java-basic-4-数据类型
Number类 装箱:将内置数据类型作为包装类对象使用:拆箱:相反 public class test{ public static void main(String args[]) { // box ...
- Linux学习-CentOS 7.x 预设启动的服务简易说明
这里 仅介绍几个很常见的 daemons 而已,更多的信息呢,就得要麻烦你自己使用 systemctl list-unit-files --type=service 去查询.底下的建议主要是针对 Li ...