题解-CodeForces835F Roads in the Kingdom
Problem
题意:求基环树删去环上任意一边后直径最小值,直径定义为所有点对最近距离的最大值
Solution
首先明确删去环上一点是不会影响树内直径的,所以应当先把所有树的直径求出来,这是树形Dp可以解决的,同时建议使用树形Dp,可以一次性求出接下来要用到的数据
这是直径在树上的情况,接下来考虑直径从树开始,中途经过环,最后回到树的情况
我们先把每个点向树里头能走的最远距离(也就是带权深度)\(f[x]\)求出来,同时把环排成一行,放到栈里头\(st[1]\)~\(st[top]\),同时把这个环边权的前缀和求出来,放到数组\(pre\)里面
考虑删去边\((st[d],st[d+1])\)
则最远点对\((x,y)\)有这两种情况:
- \(case~1~(1\leq x\leq y\leq d~or~d+1\leq x\leq y\leq n): ans=f[x]-pre[x]+f[y]+pre[y]\)
- \(case~2~(1\leq x\leq d,d+1\leq y\leq n): ans=f[x]+pre[x]+f[y]-pre[y]+pre[n]\)
由于我们需要快速求出删去每一条边的最远点对,所以可以考虑维护前缀后缀最大值:
\(gl_x=\max\{f_i-pre_i\big|i\in[1,x]\}\)
\(gr_x=\max\{f_i-pre_i\big|i\in[x,n]\}\)
\(hl_x=\max\{f_i+pre_i\big|i\in[1,x]\}\)
\(hr_x=\max\{f_i+pre_i\big|i\in[x,n]\}\)
这样的话,最远距离\(ans\)可以转化为\(ans=\max(fl_d+hl_d,fr_{d+1}+hr_{d+1},pre_n-hl_d+gr_{d+1})\)
由于这是个环,记得特殊考虑删去边\((top,1)\)
还有一点需要注意,就是加起来的两个值不能在同一个地方取到,比如说\(fl_2=f_1-pre_1,hl_2=f_1+pre_1\),则\(fl_2\)和\(hl_2\)加起来是没有意义的,需要舍去,所以我们对于每个数组还需要维护一个次大值
(⊙v⊙)嗯,你没看错,就是八个数组
Code
如果需要解释的话,\(get\_cir\)是找环的,\(dfs\)是处理树的情况的,\(work\)是处理环的
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register
template <typename _Tp> inline _Tp read(_Tp&x){
char c11=getchar(),ob=0;x=0;
while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')ob=1,c11=getchar();
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}
const int N=201000;const ll inf=0x3f3f3f3f3f3f3f3f;
struct Edge{int v,nxt,w;}a[N<<1];
int head[N],is[N],st[N],vis[N];
ll f[N],pre[N];
int gl[N],gr[N],hl[N],hr[N],hhl[N],hhr[N],ggl[N],ggr[N];
int n,m,_,top;ll Ans;
void get_cir(int x,int las){
if(vis[x]){
int p=top;
while(st[p]^x)--p;
for(rg int i=p;i<=top;++i)
is[st[i-p+1]=st[i]]=1;
st[0]=-1;top-=p-1;
return ;
}vis[st[++top]=x]=1;
for(int i=head[x];i&&~st[0];i=a[i].nxt)
if(a[i].v^las)get_cir(a[i].v,x);
if(~st[0])vis[st[top--]]=0;
}
void dfs(int x,int las){
ll sec=0ll;
for(int i=head[x];i;i=a[i].nxt)
if(!is[a[i].v]&&a[i].v^las){
dfs(a[i].v,x);f[a[i].v]+=a[i].w;
if(f[a[i].v]>=f[x])sec=f[x],f[x]=f[a[i].v];
else if(f[a[i].v]>sec)sec=f[a[i].v];
}
Ans=max(Ans,f[x]+sec);
}
inline ll G(int x){return x?f[st[x]]-pre[x]:-inf;}
inline ll H(int x){return x?f[st[x]]+pre[x]:-inf;}
void work(){
st[0]=st[top];
for(rg int x=1;x<=top;++x){
for(rg int i=head[st[x-1]];i;i=a[i].nxt)
if(a[i].v==st[x]){
pre[x]=pre[x-1]+a[i].w;
break;
}
dfs(st[x],0);
}
for(rg int i=1;i<=top;++i){
gl[i]=gl[i-1],ggl[i]=ggl[i-1];
hl[i]=hl[i-1],hhl[i]=hhl[i-1];
if(G(i)>G(gl[i]))ggl[i]=gl[i],gl[i]=i;
else if(G(i)>G(ggl[i]))ggl[i]=i;
if(H(i)>H(hl[i]))hhl[i]=hl[i],hl[i]=i;
else if(H(i)>H(hhl[i]))hhl[i]=i;
}
for(rg int i=top;i;--i){
gr[i]=gr[i+1],ggr[i]=ggr[i+1];
hr[i]=hr[i+1],hhr[i]=hhr[i+1];
if(G(i)>G(gr[i]))ggr[i]=gr[i],gr[i]=i;
else if(G(i)>G(ggr[i]))ggr[i]=i;
if(H(i)>H(hr[i]))hhr[i]=hr[i],hr[i]=i;
else if(H(i)>H(hhr[i]))hhr[i]=i;
}
ll ans;
if(hl[top]!=gl[top])ans=G(gl[top])+H(hl[top]);
else ans=max(G(ggl[top])+H(hl[top]),G(gl[top])+H(hhl[top]));
for(rg int i=1;i<top;++i){
ll val=pre[top]+H(hl[i])+G(gr[i+1]);
ll tmp;
if(gl[i]^hl[i])tmp=G(gl[i])+H(hl[i]);
else tmp=max(G(ggl[i])+H(hl[i]),G(gl[i])+H(hhl[i]));
val=max(val,tmp);++i;
if(gr[i]^hr[i])tmp=G(gr[i])+H(hr[i]);
else tmp=max(G(ggr[i])+H(hr[i]),G(gr[i])+H(hhr[i]));
val=max(val,tmp);--i;
ans=min(ans,val);
}cout<<max(ans,Ans)<<endl;
}
void init();void work();
int main(){init();work();return 0;}
void init(){
read(n);int u,v,w;
for(rg int i=1;i<=n;++i){
read(u),read(v),read(w);
a[++_].v=v,a[_].w=w,a[_].nxt=head[u],head[u]=_;
a[++_].v=u,a[_].w=w,a[_].nxt=head[v],head[v]=_;
}get_cir(1,1);
}
题解-CodeForces835F Roads in the Kingdom的更多相关文章
- Codeforces 835 F. Roads in the Kingdom
\(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...
- Codeforces 835 F Roads in the Kingdom(树形dp)
F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...
- codeforces 427 div.2 F. Roads in the Kingdom
F. Roads in the Kingdom time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Codeforces 835F Roads in the Kingdom (环套树 + DP)
题目链接 Roads in the Kingdom 题意 给出一个环套树的结构,现在要删去这个结构中的一条边,满足所有点依然连通. 删边之后的这个结构是一棵树,求所有删边情况中树的直径的最小值. 显 ...
- [NOI2013]快餐店 / CF835F Roads in the Kingdom (基环树)
题意 一颗基环树,选一对点使得这两个点的最短距离最大. 题解 相当于找基环树的直径,但是这个直径不是最长链,是基环树上的最短距离. 然后不会做. 然后看了ljh_2000的博客. 然后会了. 这道题最 ...
- 题解-Codeforces671D Roads in Yusland
Problem Codeforces-671D 题意概要:给定一棵 \(n\) 点有根树与 \(m\) 条链,链有费用,保证链端点之间为祖先关系,问至少花费多少费用才能覆盖整棵树(\(n-1\) 条边 ...
- CF835F Roads in the Kingdom/UOJ126 NOI2013 快餐店 树的直径
传送门--CF 传送门--UOJ 题目要求基环树删掉环上的一条边得到的树的直径的最小值. 如果直接考虑删哪条边最优似乎不太可做,于是考虑另一种想法:枚举删掉的边并快速地求出当前的直径. 对于环上的点, ...
- Codeforces 835F Roads in the Kingdom - 动态规划
题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗基环树,要求删去其中一条边,使得剩下的图形是一棵树,并且最长路的长度最短,求最长路的最短长度. 路径可以分为两部分:跨过环 和 在树内 ...
- codeforces:Roads in the Kingdom分析和实现
题目大意:国家有n个城市,还有n条道路,每条道路连通两个不同的城市,n条道路使得所有n个城市相互连通.现在国家经费不足,要关闭一条道路.国家的不便度定义为国家中任意两个不同的城市之间的距离的最大值,那 ...
随机推荐
- Kafka技术内幕 读书笔记之(五) 协调者——协调者处理请求
消费者客户端使用“消费者的协调者对象”( ConsumerCoordinator )来代表所有和服务端协调者节点有关的请求处理,比如心跳请求.获取和提交分区的偏移量(自动提交任务).发送“加入组请求” ...
- 转载 --- SKLearn中预测准确率函数介绍
混淆矩阵 confusion_matrix 下面将一一给出'tp','fp','fn'的具体含义: 准确率: 所有识别为"1"的数据中,正确的比率是多少. 如识别出来100个结果是 ...
- git步骤
1.New一个Repositories 2.拿到这个仓库的URL 3.git clone https://github.com/zhuobo/new.git 4.进入到clone下来的文件夹,然后gi ...
- Tornado的异步非阻塞
阻塞和非阻塞Web框架 只有Tornado和Node.js是异步非阻塞的,其他所有的web框架都是阻塞式的. Tornado阻塞和非阻塞两种模式都支持. 阻塞式: 代表:Django.Flask.To ...
- JS获得元素相对位置坐标getBoundingClientRect()
getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 1.语法:这个方法没有参数. rectObject = ...
- JS中var、let、const区别? 用3句话概括
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象: 使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升: 使用const声明的是常量,在后面出现的代码中不能再修 ...
- IScroll基本用法
一.为了防止手机上卡顿:1.从新设置一下焦点.2. <script>try { window.PointerEvent = undefined; } catch (e) { } </ ...
- spring boot2 整合(一)Mybatis (特别完整!)
大概介绍下流程: 借助idea实现mybatis逆向工程 用xml配置实现整合 用cmd命令行实现mybatis逆向工程 用mapping.xml配置实现数据交互 用注解的方式实现数据交互 首先我的开 ...
- 三十七、Linux 线程——线程清理和控制函数、进程和线程启动方式比较、线程的状态转换
37.1 线程清理和控制函数 #include <pthread.h> void pthread_cleanup_push(void (* rtn)(void *), void *arg) ...
- Burpsuite之Burp Collaborator模块介绍
Burp Collaborator.是从Burp suite v1.6.15版本添加的新功能,它几乎是一种全新的渗透测试方法.Burp Collaborator.会渐渐支持blind XSS,SSRF ...