题目

  如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌

图(cactus)。所谓简单回路就是指在图上不重复经过任何一个顶点的回路。



  举例来说,上面的第一个例子是一张仙人图,而第二个不是——注意到它有三条简单回路:(4,3,2,1,6

,5,4)、(7,8,9,10,2,3,7)以及(4,3,7,8,9,10,2,1,6,5,4),而(2,3)同时出现在前两

个的简单回路里。另外,第三张图也不是仙人图,因为它并不是连通图。显然,仙人图上的每条边,或者是这张仙

人图的桥(bridge),或者在且仅在一个简单回路里,两者必居其一。定义在图上两点之间的距离为这两点之间最

短路径的距离。定义一个图的直径为这张图相距最远的两个点的距离。现在我们假定仙人图的每条边的权值都是1

,你的任务是求出给定的仙人图的直径。

输入格式

  输入的第一行包括两个整数n和m(1≤n≤50000以及0≤m≤10000)。其中n代表顶点个数,我们约定图中的顶

点将从1到n编号。接下来一共有m行。代表m条路径。每行的开始有一个整数k(2≤k≤1000),代表在这条路径上

的顶点个数。接下来是k个1到n之间的整数,分别对应了一个顶点,相邻的顶点表示存在一条连接这两个顶点的边

。一条路径上可能通过一个顶点好几次,比如对于第一个样例,第一条路径从3经过8,又从8返回到了3,但是我们

保证所有的边都会出现在某条路径上,而且不会重复出现在两条路径上,或者在一条路径上出现两次。

输出格式

  只需输出一个数,这个数表示仙人图的直径长度。

输入样例

样例1:

15 3

9 1 2 3 4 5 6 7 8 3

7 2 9 10 11 12 13 10

5 2 14 9 15 10

样例2:

10 1

10 1 2 3 4 5 6 7 8 9 10

输出样例

样例1:

8

样例2:

9

提示

对第一个样例的说明:如图,6号点和12号点的最短路径长度为8,所以这张图的直径为8。



【注意】使用Pascal语言的选手请注意:你的程序在处理大数据的时候可能会出现栈溢出。

如果需要调整栈空间的大小,可以在程序的开头填加一句:{$M 5000000},其中5000000即

指代栈空间的大小,请根据自己的程序选择适当的数值。

题解

仙人掌入门题QAQ

看了好久题解,终于弄懂了。

想着自己肝,结果代码能力太差还是没处理好。

最后参照了下黄学长的代码A了

【月考D1爆炸中,仍在机房浪】

仙人掌

仙人掌,相信大家听得非常的多,一定也对其产生过浓厚兴趣。

其实仙人掌,说白了就是一棵树,上边套着很多的简单环,环间互不干涉,可以单独处理。【严谨定义见题目】

举一个比较直观的例子:【画得略丑】



环间互不干涉,这是一个很优美的性质,根据它我们可以得到了仙人图上的dp算法

①首先我们看看如果是一棵单纯的树怎么做:

如果是树,其实就是求树的直径,即树上最远的两个点的距离

树形dp非常简单:

令f[i]表示i节点往下到叶子最深的路径的长度

f[i]=maxf[son]+1;

由于f[i]对于儿子逐个更新,在更新到儿子3的时候,f[i]里存的是儿子1、2更新完的答案,此时f[i]+f[son3]+1即表示f[i]的前两个儿子中经过i节点到达3儿子所在子树所形成的最长路径长度,可用来同步更新答案ans=max(ans,f[u]+f[son]+1)

最后面跑完,答案就是所求

②加上环

加上环之后我们只需要单独考虑环带来的影响。

什么意思?如图:



环上每个点都有属于自己的外向树,我们在dfs更新f[i]时忽略与i处于一个环上的点,此时环上所有点的f[i]都指自己外向树中的最大深度

我们就可以跑一遍环上的dp来更新答案,用单调队列优化,最后再把最高点的f[i]更新了就好【因为f[i]往上还要更新别的点】

如何操作?

更新答案

首先对于环上两点i,j (i > j)我们有ans=max(ans,f[i]+f[j]+min(i−j,n−i+j)

我们可以将环拆开,延长一倍,用单调队列优化。队首元素与当前元素距离不得超过环的一半,这样就保证了一定是从最近路径更新的,保证了答案的正确性和完整性

更新最高点f[rt]

枚举即可,详见代码

蒟蒻要上晚自习回去复习月考了,先简单写到这,改天写详细些

【已upd】

放代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 50005,maxm = 10000005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int n,m,h[maxn],ne = 0;
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
int fa[maxn],dep[maxn],dfn[maxn],low[maxn],f[maxn],st[maxn],top = 0,cnt = 0;
int ans = 0,cir[2 * maxn],ci = 0,q[2 * maxn],head,tail,N;
void DP(int rt,int u){
int ci = dep[u] - dep[rt] + 1;
for (int i = u; i != rt; i = fa[i])
cir[ci--] = f[i];
cir[ci] = f[rt];
ci = dep[u] - dep[rt] + 1;
for (int i = 1; i <= ci; i++) cir[ci + i] = cir[i];
N = ci << 1; head = tail = 1; q[tail] = 1;
for (int i = 2; i <= N; i++){
while (i - q[head] > (ci >> 1)) head++;
ans = max(ans,cir[i] + i - q[head] + cir[q[head]]);
while (head <= tail && cir[i] - i >= cir[q[tail]] - q[tail]) tail--;
q[++tail] = i;
}
for (int i = 2; i <= ci; i++)
f[rt] = max(f[rt],cir[i] + min(i - 1,ci - i + 1));
}
void dfs(int u){
dfn[u] = low[u] = ++cnt; st[++top] = u; int to;
Redge(u) if ((to = ed[k].to) != fa[u]){
if (!dfn[to]){
fa[to] = u; dep[to] = dep[u] + 1; dfs(to);
low[u] = min(low[u],low[to]);
}
else low[u] = min(low[u],dfn[to]);
if (low[to] > dfn[u])
ans = max(ans,f[u] + f[to] + 1),f[u] = max(f[u],f[to] + 1);
low[u] = min(low[u],low[to]);
}
Redge(u) if (fa[to = ed[k].to] != u && dfn[u] < dfn[to])
DP(u,to);
}
int main(){
memset(h,-1,sizeof(h));
n = RD(); m = RD(); int k,a,b;
while (m--){
if (!(k = RD())) continue;
a = RD();
for (int i = 2; i <= k; i++) b = a,a = RD(),build(b,a);
}
for (int i = 1; i <= n; i++)
if (!dfn[i]) dfs(i);
printf("%d\n",ans);
return 0;
}

BZOJ1023[SHOI2008]cactus仙人掌图 【仙人掌DP】的更多相关文章

  1. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...

  2. BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3467  Solved: 1438[Submit][Status][Discuss] Descripti ...

  3. bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图

    http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...

  4. BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...

  5. 2018.10.29 bzoj1023: [SHOI2008]cactus仙人掌图(仙人掌+单调队列优化dp)

    传送门 求仙人掌的直径. 感觉不是很难. 分点在环上面和不在环上分类讨论. 不在环上直接树形dpdpdp. 然后如果在环上讨论一波. 首先对环的祖先有贡献的只有环上dfsdfsdfs序最小的点. 对答 ...

  6. [BZOJ1023][SHOI2008]cactus仙人掌图 DP

    题目链接 套路就是先考虑一般的树上做法.求直径的dp的做法大家应该都会吧. 那么设\(dp[i]\)表示\(i\)的子树中的点到\(i\)的最大距离. 在dp的过程中 \[ ans=\max\{dp[ ...

  7. [bzoj1023][SHOI2008]cactus 仙人掌图 (动态规划)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回 ...

  8. bzoj1023: [SHOI2008]cactus仙人掌图

    学习了一下圆方树. 圆方树是一种可以处理仙人掌的数据结构,具体见这里:http://immortalco.blog.uoj.ac/blog/1955 简单来讲它是这么做的:用tarjan找环,然后对每 ...

  9. bzoj1023 [SHOI2008]cactus仙人掌图 & poj3567 Cactus Reloaded——求仙人掌直径

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023    http://poj.org/problem?id=3567 仙人掌!直接模仿 ...

随机推荐

  1. C++使用GDI+实现图片格式转换

    主要是我在设置壁纸时遇到的个小问题,因为设置壁纸只能是bmp格式的图片,不可能我喜欢的壁纸就都是bmp格式的,就想怎么转换一下图片的格式,于是就在百度搜怎么弄,搜到了可行方法,却没有实现代码,有些看起 ...

  2. Docker自学纪实(四)搭建LNMP部署wordpress

    我们在工作中最常用的就是LNMP网站平台 这个架构呢,是整个公司网站的核心 如果对于访问量较小的网站,可以直接在服务器上面部署 而如果是访问量很大的网站,那负载就是个很大的问题. 要么需要再买很多服务 ...

  3. 路由器基础配置之rip

    我们将以上面的拓扑图进行实验,用rip协议来进行实验,目的是实现三台不同网段的pc机之间实现互相通信 首先为pc机配置好ip地址和网关,配置完IP地址后在配置路由器 router1: enable 进 ...

  4. java @override 全部报错

    问.java @override 全部报错 答: 错误:在 eclipse 的新工作空间开发项目时,出现大面积方法编译错误.鼠标放在方法名上后显示让我们去掉 @override 注解 原因: @Ove ...

  5. 一行代码搞定checkbox全选和全不选

    <!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...

  6. rootfls(根操作系统)

    rootfs根文件系统,linux下的任何目录都是rootfs的一个路径 Files 文件 Directory   目录 FHS(文件层级标准)规定了linux发行标准,也就是一些固定的文件存储 文件 ...

  7. Codeforces146D 概率DP

    Bag of mice The dragon and the princess are arguing about what to do on the New Year's Eve. The drag ...

  8. 删除警告的方法 python

    import warningswarnings.filterwarnings('ignore')

  9. android IPC 进程间通讯

    参考资料: http://blog.csdn.net/birdsaction/article/details/39451849 在这里我说一下学习技术的方法,别人的博客,别人的东西,再简单,自己没有写 ...

  10. JAVA中使用AES加密解密

    技术交流群: 233513714 /** * AES加密测试 * * @param str 加密参数 */ public void aesTest(String str) { log.info(&qu ...