BZOJ1791或洛谷4381 [IOI2008]Island
一道基环树的直径
BZOJ原题链接
洛谷原题链接
又是一道实现贼麻烦的题。。
显然公园其实是基环树森林,求的最长距离其实就是求每一棵基环树的直径的总和。
对于每棵基环树,其直径要么经过环,要么是某个环上点的子树的直径。所以我们可以先找出它的环,然后对环上的每个点进行\(dfs\)(不能经过环上的点),找出该点的子树的直径和数组\(D\),表示该点到子树中的叶子节点的最大距离。
然后考虑经过环的距离,设当前枚举到两个点\(x,y\),则长度为\(D[x]+D[y]+dis(x,y)\),这个可以通过单调队列来优化,维护一个最大值即可。
#include<cstdio>
using namespace std;
const int N = 1e6 + 10;
typedef long long ll;
int fi[N], di[N << 1], da[N << 1], ne[N << 1], cr[N], cr_d[N], q[N << 1], po[N << 1], l, cb, fp, n;
ll D[N], dis[N << 1], fr;
bool v[N], egv[N << 1], vis[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c<'0' || c>'9'; c = getchar())
p |= c == '-';
for (; c >= '0'&&c <= '9'; c = getchar())
x = x * 10 + (c - '0');
return p ? -x : x;
}
inline void add(int x, int y, int z)
{
di[++l] = y;
da[l] = z;
ne[l] = fi[x];
fi[x] = l;
}
inline ll maxn(ll x, ll y)
{
return x > y ? x : y;
}
void dfs(int x)
{
int i, y;
v[x] = 1;
for (i = fi[x]; i; i = ne[i])
{
y = di[i];
if (!egv[i])
{
cr[y] = x;
cr_d[y] = da[i];
egv[i] = egv[i & 1 ? i + 1 : i - 1] = 1;
if (v[y])
cb = y;
dfs(y);
}
}
}
void dfs_2(int x, ll d, int fa)
{
int i, y;
if (fr < d)
{
fr = d;
fp = x;
}
for (i = fi[x]; i; i = ne[i])
{
y = di[i];
if (!vis[y] && y != fa)
{
dfs_2(y, d + da[i], x);
D[x] = maxn(D[x], D[y] + da[i]);
}
}
}
void dfs_3(int x, ll d, int fa)
{
int i, y;
fr = maxn(fr, d);
for (i = fi[x]; i; i = ne[i])
{
y = di[i];
if (!vis[y] && y != fa)
dfs_3(y, d + da[i], x);
}
}
int main()
{
int i, j, x, y, k, head, tail;
ll s = 0, ma;
n = re();
for (i = 1; i <= n; i++)
{
x = re();
y = re();
add(i, x, y);
add(x, i, y);
}
for (i = 1; i <= n; i++)
if (!v[i])
{
ma = 0;
dfs(i);
j = cb;
k = 0;
do
{
vis[j] = 1;
k++;
dis[k + 1] = dis[k] + cr_d[j];
po[k] = j;
j = cr[j];
} while (j^cb);
do
{
vis[j] = 0;
fr = 0;
dfs_2(j, 0, 0);
fr = 0;
dfs_3(fp, 0, 0);
vis[j] = 1;
ma = maxn(ma, fr);
k++;
dis[k + 1] = dis[k] + cr_d[j];
po[k] = j;
j = cr[j];
} while (j^cb);
head = 1;
tail = 0;
for (j = 1; j <= k; j++)
{
while (j - q[head] >= (k >> 1))
head++;
if (head <= tail)
ma = maxn(ma, D[po[j]] + D[po[q[head]]] + dis[j] - dis[q[head]]);
else
ma = maxn(ma, D[po[j]]);
while (head < tail&&D[po[j]] - dis[j] >= D[po[q[tail]]] - dis[q[tail]])
tail--;
q[++tail] = j;
}
s += ma;
}
printf("%lld", s);
return 0;
}
BZOJ1791或洛谷4381 [IOI2008]Island的更多相关文章
- luogu 4381 [IOI2008]Island 单调队列 + 基环树直径 + tarjan
Description 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样 ...
- BZOJ1791: [Ioi2008]Island 岛屿
BZOJ1791: [Ioi2008]Island 岛屿 Description 你将要游览一个有N个岛屿的公园. 从每一个岛i出发,只建造一座桥. 桥的长度以Li表示. 公园内总共有N座桥. 尽管每 ...
- [bzoj1791][ioi2008]Island 岛屿(基环树、树的直径)
[bzoj1791][ioi2008]Island 岛屿(基环树.树的直径) bzoj luogu 题意可能会很绕 一句话:基环树的直径. 求直径: 对于环上每一个点记录其向它的子树最长路径为$dp_ ...
- bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1826 Solved: 405[Submit][S ...
- bzoj千题计划114:bzoj1791: [Ioi2008]Island 岛屿
http://www.lydsy.com/JudgeOnline/problem.php?id=1791 就是求所有基环树的直径之和 加手工栈 #include<cstdio> #incl ...
- 【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)
题目: 洛谷3224 分析: 这题一看\(n\leq100000\)的范围就知道可以暴力地用\(O(nlogn)\)数据结构乱搞啊-- 每个联通块建一棵Splay树,查询就是Splay查询第k大的模板 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
随机推荐
- atrous convolution
atrous convolution 简而言之,带孔卷积: 来自:https://zhuanlan.zhihu.com/p/27470685 假设一个二维信号,每个位置对应的输出为和卷积核为,带孔卷积 ...
- DM 9000网卡驱动移植
1. 由于内核已经带有DM9000 网卡的驱动,所以主要移植工作是在板文件中添加 platform_device 结构,并加入 ok6410_devices[] __initdata 数组. 代码如下 ...
- 微信小程序如何提交审核并发布?发布问题:小程序只支持https访问
http://www.jisuapp.cn/news/305.html 发布问题:1.小程序只支持https访问 2.要配置服务域名
- python 自然语言处理库https://www.nltk.org/nltk_data/
https://www.nltk.org/nltk_data/ https://github.com/hankcs/HanLP
- spring的aop的例子
一个简单的Spring的AOP例子 2009-06-23 11:33:29| 分类: Spring | 标签: |举报 |字号大中小 订阅 package aop; /** * 目标对象的 ...
- Python基础之列表及元组的增删改查
定义一个列表 晚上的状态不太适合写博客,容易犯困~ 列表的增加有三种方式 第一种主流的增加 append函数 list1 = ['noevil', 'fordearme', 'city', 'cust ...
- PHP ActiveRecord demo栗子中 关于类名 的问题
问题: ActiveRecord如何将单个类名与表名相关联? 我昨天才发现了ActiveRecord,很奇妙的php数据库框架. 但是,我仍然对以下工作感到困惑: 1.下面这个Person Model ...
- css3 vw、vh属性详解,以及与%、rem的区别介绍
最近的项目需求,内嵌电视端显示页面,所以使用到了css3的属性:vw \ vh,遇到一些问题,记录下来 vw.vh是什么? 字面上可以简单理解为,vw (view width),vh(view hei ...
- 第十章 优先级队列 (b3)完全二叉堆:删除与下滤
- numpy.random.uniform()
numpy.random.uniform均匀分布 2018年06月19日 23:28:03 徐小妹 阅读数:4238 numpy.random.uniform介绍: 1. 函数原型: numpy ...