「BZOJ 3242」「NOI 2013」快餐店「基环树」
题意
基环树上找到一个点(可以在边上)使得它到树上最远点的距离最小,输出最小距离
题解
如果是一棵树,答案就是树的直径\(/2\)
如果是基环树,那么很好证明删去环上的某一条边是不影响答案的。于是断环为链,单调队列维护\(dep+sum,dep-sum\)的最大值和次大值,然后算直径,如果两个最大值是同个结点就取一个次大,否则都取最大。
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
struct Edge {
int v, w, nxt;
} e[N << 1];
int hd[N], p;
void link(int u, int v, int w) {
e[p] = (Edge) {v, w, hd[u]};
hd[u] = p ++;
}
int n, dfn[N], idx;
int fa[N], fw[N], c[N], d[N], cnt;
bool cir[N];
void dfs(int u, int cur = -1) {
dfn[u] = ++ idx;
for(int i = hd[u]; ~ i; i = e[i].nxt) if(i != cur) {
int v = e[i].v, w = e[i].w;
if(!dfn[v]) {
fa[v] = u; fw[v] = w; dfs(v, i ^ 1);
} else if(dfn[v] < dfn[u]) {
cnt ++; cir[c[cnt] = u] = 1; d[cnt] = w;
for(int j = u; j != v; j = fa[j]) {
cnt ++; cir[c[cnt] = fa[j]] = 1; d[cnt] = fw[j];
}
}
}
}
ll mdep[N][2], tree_d;
void dfs2(int u, int f = -1) {
for(int i = hd[u]; ~ i; i = e[i].nxt) {
int v = e[i].v;
if(v == f || cir[v]) continue ;
dfs2(v, u);
ll dis = e[i].w + mdep[v][0];
if(dis > mdep[u][0]) {
mdep[u][1] = mdep[u][0];
mdep[u][0] = dis;
} else if(dis > mdep[u][1]) {
mdep[u][1] = dis;
}
}
tree_d = max(tree_d, mdep[u][0] + mdep[u][1]);
}
int main() {
scanf("%d", &n);
fill(hd + 1, hd + n + 1, -1);
for(int u, v, w, i = 1; i <= n; i ++) {
scanf("%d%d%d", &u, &v, &w);
link(u, v, w); link(v, u, w);
}
dfs(1);
static ll dep[N << 1], sum[N << 1], ans = 1ll << 62;
for(int i = 1; i <= cnt; i ++) {
dfs2(c[i]);
dep[i] = dep[i + cnt] = mdep[c[i]][0];
}
for(int i = 1; i <= cnt << 1; i ++)
sum[i] = sum[i - 1] + d[i > cnt ? i - cnt : i];
static int q1[N << 1], l1, r1;
static int q2[N << 1], l2, r2;
#define val1(u) dep[u] - sum[u]
#define val2(u) dep[u] + sum[u]
for(int i = 1; i <= cnt << 1; i ++) {
for(; l1 < r1 && q1[l1] + cnt - 1 < i; l1 ++) ;
for(; r1 - l1 > 1 && q1[l1 + 1] + cnt - 1 < i; l1 ++) q1[l1 + 1] = q1[l1];
for(; l2 < r2 && q2[l2] + cnt - 1 < i; l2 ++) ;
for(; r2 - l2 > 1 && q2[l2 + 1] + cnt - 1 < i; l2 ++) q2[l2 + 1] = q2[l2];
for(; r1 - l1 > 2 && val1(q1[r1 - 1]) <= val1(i); r1 --) ;
q1[r1 ++] = i;
if(r1 - l1 <= 3) {
for(int j = r1 - 1; j > l1; j --)
if(val1(q1[j]) > val1(q1[j - 1])) swap(q1[j], q1[j - 1]);
}
for(; r2 - l2 > 2 && val2(q2[r2 - 1]) <= val2(i); r2 --) ;
q2[r2 ++] = i;
if(r2 - l2 <= 3) {
for(int j = r2 - 1; j > l2; j --)
if(val2(q2[j]) > val2(q2[j - 1])) swap(q2[j], q2[j - 1]);
}
if(i >= cnt && r1 - l1 > 1) {
int a1 = q1[l1], a2 = q1[l1 + 1];
int b1 = q2[l2], b2 = q2[l2 + 1];
ll cir_d = 0;
if(a1 == b1) cir_d = max(val1(a1) + val2(b2), val1(a2) + val2(b1));
else cir_d = val1(a1) + val2(b1);
ans = min(ans, max(tree_d, cir_d));
}
}
printf("%lld.%c\n", ans >> 1, ans & 1 ? '5' : '0');
return 0;
}
\(\text{Codeforces 835F}\)是一样的题,数据范围乘\(2\),改一下输出就行.
什么,\(\text{Wrong Answer}\)?
我觉得这是一个错误的解法,回头有时间更新一种用前后缀的做法。
如果我几个月都没更 可以在评论里捶我
「BZOJ 3242」「NOI 2013」快餐店「基环树」的更多相关文章
- 「BZOJ 1791」「IOI 2008」Island「基环树」
题意 求基环树森林所有基环树的直径之和 题解 考虑的一个基环树的直径,只会有两种情况,第一种是某个环上结点子树的直径,第二种是从两个环上结点子树内的最深路径,加上环上这两个结点之间的较长路径. 那就找 ...
- Solution -「基环树」做题记录
写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...
- 【BZOJ 3242】【UOJ #126】【CodeVS 3047】【NOI 2013】快餐店
http://www.lydsy.com/JudgeOnline/problem.php?id=3242 http://uoj.ac/problem/126 http://codevs.cn/prob ...
- BZOJ - 3242 :快餐店 (基环树DP) 最小化半径
题意:给定N点N边的无向连通图,现在让你在图中找一点作为餐厅,使得最远点距离这点最近. 思路:为了保留整数,我们求最小直径,最后去除2. 直径来源于两部分: 1,在外向树中: 那么就是树的直接,一棵 ...
- bzoj 2878: [Noi2012]迷失游乐园【树上期望dp+基环树】
参考:https://blog.csdn.net/shiyukun1998/article/details/44684947 先看对于树的情况 设d[u]为点u向儿子走的期望长度和,du[u]为u点的 ...
- 「BZOJ 4228」Tibbar的后花园
「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...
- 「BZOJ 3645」小朋友与二叉树
「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...
- 「BZOJ 4502」串
「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...
- 「BZOJ 4289」 PA2012 Tax
「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...
随机推荐
- C# 单例模式代码
原文地址:http://blog.jobbole.com/101746/ 代码一: public sealed class Singleton { static Singlet ...
- (转)nodejs搭建本地http服务器
本文转载自:http://www.cnblogs.com/shawn-xie/archive/2013/06/06/3121173.html 由于不做php相关的东西,懒得装apache,干脆利用no ...
- java代码继承。。。找出不能继承父类方法的问题
总结:当子类中没有定义name属性时,在子类的无参构造方法中,父类的姓名是不能被继承的. 输出的结果是,子类无参构造方法里的属性值,也就是是属 控制台显示: 我叫:周杰伦,今年:2岁我的姓名:周杰伦, ...
- java代码包装类----------Integer
总结:我的笔试挂了..基础的继承不懂不会.我不知道到底是哪里的问题. 要好好反思 package com.da.ima2; public class jrfk { // int整型不能直接转化为Int ...
- 2018年长沙理工大学第十三届程序设计竞赛 H数学考试
链接:https://www.nowcoder.com/acm/contest/96/H来源:牛客网 数学考试 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...
- 基于OpenCV的火焰检测(一)——图像预处理
博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测.在做这个项目的时候,博主参考了很多相关的文献,用了很多种 ...
- Install boot2docker defaule username and password
username passowrd method docker tcuser ssh root command sudo -i
- 问题:c# json解析;结果:c# 解析JSON的几种办法
c# 解析JSON的几种办法 欲成为海洋大师,必知晓海中每一滴水的真名. 刚开始只是想找一个转换JSON数组的方法,结果在MSDN翻到一大把. 搜索过程中免不了碰到一大堆名词:WCF => Da ...
- 关于win7 下双击不能打开jar 文件
关于这个问题解决如下: 我的java 安装路径为C:\java\jdk1.6\bin 1,首先检查jdk 的路径是否安装正确. 2,导出jar 包时,是否有添加 main class. 如果通过在do ...
- MSSQL 日期查询 包含NULL值
方一: 以下做法保证数据里面没有NULL值 '') '') '') '') exec sp_executesql N'select ide_code as ''系统编号'',name as ''申请专 ...