bzoj1023: [SHOI2008]cactus仙人掌图
学习了一下圆方树。
圆方树是一种可以处理仙人掌的数据结构,具体见这里:http://immortalco.blog.uoj.ac/blog/1955
简单来讲它是这么做的:用tarjan找环,然后对每个环建立一个新点,然后将环上的边删去,并环上的每个点都连到新点上。这样我们就可以把一个环缩成一个菊花图,重复这么做,一棵仙人掌就变成一棵树啦!这棵树就叫做圆方树,其中原点叫圆点,新点叫方点。
圆方树和原仙人掌很相似,而且它又是一棵树,于是我们就可以在上面dp啦!不过要注意的是对于方点的处理,不能直接更新,要作一个单调队列,因为环上有两种走法么。
期间调了很久,而且我还不会生成数据,orz cbh。
tarjan求DCC都不会写了,我好弱啊~
#include <bits/stdc++.h>
#define N 110000
using namespace std;
int n, m, nn;
vector <int> V[N], W[N];
int low[N], dfn[N], dfsnum;
int f[N];
int ans;
int shed[N], top;
deque <int> Q;
void tarjan(int t, int f)
{
dfn[t] = low[t] = ++ dfsnum;
shed[++ top] = t;
for (int p = ; p < V[t].size(); ++ p)
if (V[t][p] != f) if (!dfn[V[t][p]])
{
tarjan(V[t][p], t);
low[t] = min(low[t], low[V[t][p]]);
if (low[V[t][p]] >= dfn[t])
{
if (shed[top] != V[t][p])
{
nn ++;
int cur;
do
{
//W[shed[top]].push_back(nn);
W[nn].push_back(cur = shed[top]);
shed[top --] = ;
}
while (cur != V[t][p]);
W[t].push_back(nn);
//W[nn].push_back(t);
}
else
{
W[t].push_back(shed[top]);
//W[shed[top]].push_back(t);
shed[top --] = ;
}
}
}
else low[t] = min(low[t], dfn[V[t][p]]);
}
void dfs(int t)
{
f[t] = ;
int s = W[t].size();
if (t > n)
{
for (int p = ; p < s; ++ p)
dfs(W[t][p]);
for (int q = ; q < (s + ) / ; ++ q)
{
while (!Q.empty() && f[W[t][Q.back()]] + Q.back() < f[W[t][q]] + q) Q.pop_back();
Q.push_back(q);
}
for (int p = , q = (s + ) / ; p < s; ++ p, q = (q == s? : q + ) )
{
if (q != s)
{
while (!Q.empty() && f[W[t][Q.back()]] + (Q.back() < p? Q.back() + s + - p: Q.back() - p) < f[W[t][q]] + (q < p? q + s + - p: q - p)) Q.pop_back();
Q.push_back(q);
}
if (Q.front() == p) Q.pop_front();
if (!Q.empty()) ans = max(ans, f[W[t][p]] + f[W[t][Q.front()]] + (Q.front() > p? Q.front() - p: Q.front() + s + - p));
}
for (int p = ; p < (s + ) / ; ++ p) f[t] = max(f[t], f[W[t][p]] + p);
for (int p = (s + ) / ; p < s; ++ p) f[t] = max(f[t], f[W[t][p]] + s - - p);
Q.clear();
}
else
{
int mx1 = , mx2 = ;
for (int p = ; p < s; ++ p)
{
dfs(W[t][p]);
if (f[W[t][p]] + > mx1) mx2 = mx1, mx1 = f[W[t][p]] + ;
else if (f[W[t][p]] + > mx2) mx2 = f[W[t][p]] + ;
}
ans = max(ans, mx1 + mx2);
f[t] = mx1;
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= m; ++ i)
{
int k, a;
scanf("%d%d", &k, &a);
for (int i = ; i <= k; ++ i)
{
int b;
scanf("%d", &b);
V[a].push_back(b);
V[b].push_back(a);
a = b;
}
}
nn = n;
tarjan(, );
//puts("haha");
dfs();
printf("%d\n", ans);
}
bzoj1023: [SHOI2008]cactus仙人掌图的更多相关文章
- bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...
- BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...
- BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3467 Solved: 1438[Submit][Status][Discuss] Descripti ...
- BZOJ1023[SHOI2008]cactus仙人掌图 【仙人掌DP】
题目 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌 图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路. 举例来说 ...
- BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌)
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...
- [bzoj1023][SHOI2008]cactus 仙人掌图 (动态规划)
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回 ...
- 2018.10.29 bzoj1023: [SHOI2008]cactus仙人掌图(仙人掌+单调队列优化dp)
传送门 求仙人掌的直径. 感觉不是很难. 分点在环上面和不在环上分类讨论. 不在环上直接树形dpdpdp. 然后如果在环上讨论一波. 首先对环的祖先有贡献的只有环上dfsdfsdfs序最小的点. 对答 ...
- bzoj1023 [SHOI2008]cactus仙人掌图 & poj3567 Cactus Reloaded——求仙人掌直径
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 仙人掌!直接模仿 ...
- bzoj千题计划224:bzoj1023: [SHOI2008]cactus仙人掌图
又写了一遍,发出来做个记录 #include<cstdio> #include<algorithm> #include<iostream> using namesp ...
随机推荐
- u3d_Shader_effects笔记6 第四章 使用cubeMap简单的反射读取
一:前面心情: 1.今天开了个小会,该看的继续要看,不要堕落. 2.还有就是丽的生活习惯不太好.慢慢改变. 3.哎,公司人员争夺吗?哎,不知道,不了解,不去想,提升自己,内心明净 二.主要内容和参考 ...
- Mui沉浸模式以及状态栏颜色改变
沉浸模式只需要设置下就可以 ios: 打开应用的manifest.json文件,切换到代码视图,在plus -> distribute -> apple 下添加UIReserveSta ...
- Spring知识点提炼
原文出处: 朱小厮 1. Spring框架的作用 轻量:Spring是轻量级的,基本的版本大小为2MB 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对 ...
- php结合redis实现高并发下的抢购、秒杀功能
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- JSP之WEB服务器:Apache与Tomcat的区别 ,几种常见的web/应用服务器
注意:此为2009年的blog,注意时效性(针对常见服务器) APACHE是一个web服务器环境程序 启用他可以作为web服务器使用 不过只支持静态网页 如(asp,php,cgi,jsp)等 ...
- Python 字符串
Python访问字符串中的值 Python不支持单字符类型,单字符也在Python也是作为一个字符串使用. Python访问子字符串,可以使用方括号来截取字符串,如下实例: #!/usr/bin/py ...
- javascript数据类型判断
javascript基本数据类型:原始类型 和 引用类型 原始类型(简单数据类型):String,Number,Boolean,Undefined,Null,Symbol(ES6新增) 引用类型( ...
- python脚本实现scp上传下载功能
普通版本 1 # -*- coding:utf-8 -*- import paramiko,os,sys,time port = 22 user = 'root' def ssh_scp_put(ip ...
- 【UOJ #13】【UER #1】跳蚤OS
http://uoj.ac/problem/13 建立trie树,然后建立go指针, 和AC自动机里的fail指针差不多, 走到一个快捷方式就从go指针走. 注意在trie树上要保留字符'/',不能用 ...
- 五种开源协议(GPL,LGPL,BSD,MIT,Apache)
什么是许可协议? 什么是许可,当你为你的产品签发许可,你是在出让自己的权利,不过,你仍然拥有版权和专利(如果申请了的话),许可的目的是,向使用你产品的人提供 一定的权限. 不管产品是免费向公众分发,还 ...