bzoj 1023: [SHOI2008]cactus仙人掌图
这道题是我做的第一道仙人掌DP,小小纪念一下……
仙人掌DP就是环上的点环状DP,树上的点树上DP。就是说,做一遍DFS,DFS的过程中处理出环,环上的点先不DP,先把这些换上的点的后继点都处理出来,再从环上DFS序最小的点开始进行环状DP,就ok了。但是注意判断是不是父边不能用 v[k] != fa[now],这样如果两个点构成一个环就会出错,所以存这个点的父边,记为fb[now],这样判断的时候只需判断(k^1) != fb[now],就可以了。在环状DP的时候我想了很久怎么用单调队列优化(其实是我太弱了,环状DP都不会写=_=)。存一个p[i] = f[i]-i,然后用 f[i]+i+p[j] 更新答案就可以了,最后只需更新环最顶端的点的 f 值而不用全部修改。
这么说很笼统,还是看代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#define N 500100
#define M 1001000
using namespace std; int n, m;
int p[N], next[M], v[M], bnum = -;
int f[N] = {};
int ans = ; void addbian(int x, int y)
{
bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y;
bnum++; next[bnum] = p[y]; p[y] = bnum; v[bnum] = x;
} int nowtime = ;
int low[N], vist[N] = {}, fb[N], fa[N];
bool instack[N] = {}; int roop[N], roopnum; struct ss
{
int place, val;
}dui[N];
int head, tail; void work_circle()
{
int limit = roopnum/;
for (int i = roopnum+; i <= (roopnum<<); ++i) roop[i] = roop[i-roopnum];
ss x; x.val = f[roop[]]-; x.place = ;
head = ; tail = ; dui[head] = x;
for (int i = ; i <= (roopnum<<); ++i)
{
while (dui[head].place+limit < i) head++;
ans = max(ans, f[roop[i]]+i+dui[head].val);
x.val = f[roop[i]]-i; x.place = i;
while (dui[tail].val < x.val && tail >= head) tail--;
dui[++tail] = x;
}
} void dfs(int now)
{
int k = p[now]; vist[now] = ++nowtime; low[now] = vist[now];
while (k != -)
{
if (k != fb[now])
{
if (vist[v[k]]) low[now] = min(low[now], vist[v[k]]);
else
{
fa[v[k]] = now; fb[v[k]] = k^;
dfs(v[k]);
low[now] = min(low[now], low[v[k]]);
}
}
k = next[k];
}
k = p[now];
while (k != -)
{
if ((k^) == fb[v[k]] && low[v[k]] > vist[now])
{
ans = max(ans, f[now] + f[v[k]] + );
f[now] = max(f[now], f[v[k]] + );
}
if ((k^) != fb[v[k]] && vist[now] < vist[v[k]])
{
roopnum = ;
int x = v[k];
while (x != fa[now])
{
roop[++roopnum] = x;
x = fa[x];
}
work_circle();
for (int i = ; i < roopnum; ++i)
f[now] = max(f[now], f[roop[i]]+min(i, roopnum-i));
}
k = next[k];
}
} int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) p[i] = -;
for (int i = ; i <= m; ++i)
{
int k, x, y; scanf("%d%d", &k, &x);
for (int j = ; j < k; ++j)
{
scanf("%d", &y);
addbian(x, y);
x = y;
}
}
fa[] = ; fb[] = -; dfs();
printf("%d\n", ans);
return ;
}
bzoj 1023: [SHOI2008]cactus仙人掌图的更多相关文章
- bzoj 1023: [SHOI2008]cactus仙人掌图 tarjan缩环&&环上单调队列
1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1141 Solved: 435[Submit][ ...
- 【刷题】BZOJ 1023 [SHOI2008]cactus仙人掌图
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...
- BZOJ 1023: [SHOI2008]cactus仙人掌图 | 在仙人掌上跑DP
题目: 求仙人掌直径 http://www.lydsy.com/JudgeOnline/problem.php?id=1023 题解: 首先给出仙人掌的定义:满足所有的边至多在一个环上的无向联通图 我 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图 2125: 最短路 4728: 挪威的森林 静态仙人掌上路径长度的维护系列
%%% http://immortalco.blog.uoj.ac/blog/1955 一个通用的写法是建树,对每个环建一个新点,去掉环上的边,原先环上每个点到新点连边,边权为点到环根的最短/长路长度 ...
- bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...
- BZOJ.1023.[SHOI2008]cactus仙人掌图(DP)
题目链接 类似求树的直径,可以用(类似)树形DP求每个点其子树(在仙人掌上就是诱导子图)最长链.次长链,用每个点子节点不同子树的 max{最长链}+max{次长链} 更新答案.(不需要存次长链,求解过 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图【tarjan+dp+单调队列】
本来想先求出点双再一个一个处理结果写了很长发现太麻烦 设f[u]为u点向下的最长链 就是再tarjan的过程中,先照常处理,用最长儿子链和次长儿子链更新按ans,然后处理以这个点为根的环,也就是这个点 ...
- 1023: [SHOI2008]cactus仙人掌图 - BZOJ
Description如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路 ...
- 【BZOJ】1023: [SHOI2008]cactus仙人掌图 静态仙人掌(DFS树)
[题意]给定仙人掌图(每条边至多在一个简单环上),求直径(最长的点对最短路径).n<=50000,m<=10^7. [算法]DFS树处理仙人掌 [题解]参考:仙人掌相关问题的处理方法(未完 ...
随机推荐
- gcc中不同namespace中同名class冲突时
正常情况下,编译器都会报错,提示你有两个候选类,让你明确的选择一个. 比如我的情况,我自己设计了一个类Message, 然后在某个文件里面引用了它.但是我的文件中又引入了mongodb的头文件,非常不 ...
- [Angular 2] Create Shareable Angular 2 Components
Components that you use across multiple applications need to follow a module pattern that keeps them ...
- C语言连接MySQL数据库(课程设计总结)
刚结束课程设计,也预示着假期立即就要到来了.本次课程设计并不算难,无非就是让做一个XXX系统,实现用户的注冊.登录.菜单管理.超级用户等等一些功能,到如今为止已经做过好几个了,所以基本流程都熟悉了! ...
- 关于dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的分发机制浅析
虽说这个问题不是很难...动动手就能看出答案...但是似乎不太容易理解...几次尝试把这个问题说明白....但是好像感觉说不明白....(顿时想起了那句话----说不明白就是自己还不明白! 我怎么可能 ...
- 解决Download interrupted: Connection to https://dl-ssl.google.com refused的问题
运行->drivers->etc->hosts 加入一行 74.125.237.1 dl-ssl.google.com ok! =================上述方法已经失效, ...
- IIS 之 添加绑定域名 或 设置输入IP直接访问网站
1.打开IIS,右键站点 → 编辑绑定,弹出“网站绑定”窗口,如下图: 2.点击“添加”,弹出“添加网站绑定”窗口,如下图: 注意:若想输入 IP 地址直接访问,则可以有以下两种设置任一均可: ...
- Scheme中一些函数在C++里面的实现与吐槽
最终我失败了,这是显而意见,我试图在一个很看重类型是什么的语言中实现无类型操作,事实上,哪怕我实现了基本的cons,car,cdr,list后面的代码也无法写下去.比如说list-n,根据 ...
- oracle11g asm standalone 单实例重建
原文地址:oracle11g asm单实例重建has 作者:datapeng 最近到客户那里处理故障,客户说,他们修改了一下hostname,导到has出现了问题,当然,他们的数据库也就无法再启动,把 ...
- SQLServer-镜像配置
实验环境:三台服务器分别为主服务器,镜像服务器,见证服务器,都加入域sql.com 1. 分别在三台服务器上安装SQL 2008 R2,安装数据库引擎和管理工具两个组件即可. 2. 镜像前准备工作. ...
- LeetCode 122
Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...