题目

  如果某个无向连通图的任意一条边至多只出现在一条简单回路(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. BZOJ2005: [Noi2010]能量采集(容斥原理 莫比乌斯反演)

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 4727  Solved: 2877[Submit][Status][Discuss] Descript ...

  2. MySQL另类的备份恢复方法——innodb可传输表空间

      Preface       There're many ways in backing up or migrating data from one server to another one.Lo ...

  3. MySQL查询优化 对not in 、in 的优化

    因为 not in不走索引,所以不在不得已情况下,就不要使用not in 下面使用 join 来替代not in 做查询 select ID from A where ID not in (selec ...

  4. iOS常用控件-UIScrollView

    一. 常见属性 @property (nonatomic) CGPoint contentOffset;                      //记录UIScrollView滚动的位置 @pro ...

  5. B1086 就不告诉你 (15分)

    B1086 就不告诉你 (15分) 做作业的时候,邻座的小盆友问你:"五乘以七等于多少?"你应该不失礼貌地围笑着告诉他:"五十三."本题就要求你,对任何一对给定 ...

  6. 输入cin对象的用法

    #include<iostream> using namespace std; int main() { int carrots ; cout << "How man ...

  7. 笔记-docker-1

    笔记-docker-1 1.      简介 1.1.    什么是Docker? Docker 是世界领先的软件容器平台.开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问 ...

  8. 6.Mongodb索引

    1.索引 2.索引的命令

  9. hihocoder #1394 : 网络流四·最小路径覆盖(最小路径覆盖)

    #1394 : 网络流四·最小路径覆盖 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 国庆期间正是旅游和游玩的高峰期. 小Hi和小Ho的学习小组为了研究课题,决定趁此机 ...

  10. centos7.3配置guacamole

    目录 1 安装guacamole所需要的依赖库 2 安装配置tomcat,架设服务 2.1 下载tomcat 2.2 配置环境变量,使tomcat可以找到guacamole客户端配置 2.3 安装gu ...