【BZOJ】【1023】【SHOI2008】cactus仙人掌图
DP+单调队列/仙人掌
题解:http://hzwer.com/4645.html->http://z55250825.blog.163.com/blog/static/150230809201412793151890/
QAQ了
呃……第一次做仙人掌的题目……感觉性质还是蛮神奇的(我是不是应该先做一点环套树的题目呢?>_>)
每个点都只会在一个简单环上,所以在dfs的时候,对于一个环,它上面的点是深度连续的一段(沿着father可以遍历这个环!),然后最后一个点再指回起始点,所以只要low改变了,就找到了一个环。。。
判是否在环上也很好判,看下low就可以了
简单了解了仙人掌的情况,我们来看下这道题怎么做:
如果是一棵树的话,我们只要Tree DP就可以了……令f[i]表示以 i 为根的最长的链,子树合并的时候随便搞搞……比较简单。
现在麻烦的是出现了环= =所以f[i]的定义本身就有些纠结……
既然这样,那么我们就把问题分成两部分来做吧!树的部分和环的部分!
对于树的部分……同上aaarticlea/png;base64,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" alt="" />
那么环的部分是什么情况呢?我们可以令f[i]表示环上这个点向外的最长链的长度(这个定义对于树的部分不冲突,所以不用分开算)然后环上的最长链就是:$ans=max\{ f[i]+f[j]+min\{j-i,tot-j+i\} \}$呃……其实意思就是找环上两条链出来,然后加上它俩直接的距离求个最大值。最后需要更新一下环的“根”节点的f[root],这时它的子树已经完全计算完毕了,那么f[root]就应该表示以它为根的最长链,那么我们就可以用环上其他点连出去的链来更新这个f[root](其实之前算环上两条链的时候有一种情况算不到,现在就是在做这个哦,这句如果不理解就忽视掉吧,不是很重要……)
/**************************************************************
Problem: 1023
User: Tunix
Language: C++
Result: Accepted
Time:212 ms
Memory:9792 kb
****************************************************************/ //BZOJ 1023
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
typedef long long LL;
inline int getint(){
int v=,r=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-;
for(; isdigit(ch);ch=getchar()) v=v*+ch-'';
return v*r;
}
const int N=1e5+,INF=~0u>>;
/*********************template******************/
int to[N<<],next[N<<],head[N],cnt;
void add(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
}
int dfn[N],low[N],fa[N],dep[N],dfs_clock,a[N],Q[N],f[N];
int n,m,ans;
void dp(int root,int x){
int tot=dep[x]-dep[root]+,j=tot;
for(int i=x;i!=root;i=fa[i])
a[j--]=f[i];
a[j]=f[root];
F(i,,tot) a[i+tot]=a[i];
int l=,r=-;
Q[++r]=;
F(i,,tot*){
while(l<=r && i-Q[l]>tot/) l++;
ans=max(ans,a[i]+i+a[Q[l]]-Q[l]);
while(l<=r && a[Q[r]]-Q[r]<a[i]-i) r--;
Q[++r]=i;
}
F(i,,tot)
f[root]=max(f[root],a[i]+min(i-,tot-i+));
}
void dfs(int x){
dfn[x]=low[x]=++dfs_clock;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa[x]){
if (!dfn[to[i]]){
fa[to[i]]=x;
dep[to[i]]=dep[x]+;
dfs(to[i]);
low[x]=min(low[x],low[to[i]]);
}else low[x]=min(low[x],dfn[to[i]]);
if (dfn[x]<low[to[i]]){
ans=max(ans,f[x]+f[to[i]]+);
f[x]=max(f[x],f[to[i]]+);
}
}
for(int i=head[x];i;i=next[i])
if (fa[to[i]]!=x && dfn[x]<dfn[to[i]])
dp(x,to[i]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1023.in","r",stdin);
freopen("std.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,,m){
int k=getint(),a=getint(),b;
F(i,,k){
b=getint();
add(a,b);
a=b;
}
}
dfs();
printf("%d\n",ans);
return ;
}
1023: [SHOI2008]cactus仙人掌图
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 1329 Solved: 532
[Submit][Status][Discuss]
Description
如果某个无向连通图的任意一条边至多只出现在一条简单回路(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,你的任务是求
出给定的仙人图的直径。
Input
输入的第一行包括两个整数n
和m(1≤n≤50000以及0≤m≤10000)。其中n代表顶点个数,我们约定图中的顶点将从1到n编号。接下来一共有m行。代表m条路径。每行的开
始有一个整数k(2≤k≤1000),代表在这条路径上的顶点个数。接下来是k个1到n之间的整数,分别对应了一个顶点,相邻的顶点表示存在一条连接这两
个顶点的边。一条路径上可能通过一个顶点好几次,比如对于第一个样例,第一条路径从3经过8,又从8返回到了3,但是我们保证所有的边都会出现在某条路径
上,而且不会重复出现在两条路径上,或者在一条路径上出现两次。
Output
只需输出一个数,这个数表示仙人图的直径长度。
Sample Input
9 1 2 3 4 5 6 7 8 3
7 2 9 10 11 12 13 10
5 2 14 9 15 10 8
10 1
10 1 2 3 4 5 6 7 8 9 10
Sample Output
HINT
对第一个样例的说明:如图,6号点和12号点的最短路径长度为8,所以这张图的直径为8。
【注意】使用Pascal语言的选手请注意:你的程序在处理大数据的时候可能会出现栈溢出。如果需要调整栈空间的大小,可以在程序的开头填加一句:{$M 5000000},其中5000000即指代栈空间的大小,请根据自己的程序选择适当的数值。
Source
【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就是环上的点环状DP,树上的点树上DP.就是说,做一遍DFS,DFS的过程中处理出环,环上的点先不DP,先把这些换上的点的后继点都处理出来, ...
- 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树处理仙人掌 [题解]参考:仙人掌相关问题的处理方法(未完 ...
随机推荐
- [原创] 初识Agile/CMMI/Scrum
一.背景介绍 在朋友(aehyok)的建议下,初步去了解Visual Studio Online,简称VS Online(即原来的 Team Foundation Service,简称TFS) VS ...
- html5面向对象做一个贪吃蛇小游戏
canvas加面向对象方式的贪吃蛇 2016-08-25 这个小游戏可以增加对面向对象的理解,可以加强js逻辑能力,总之认真自己敲一两遍收获还是不少啊!!适合刚学canvas的同学练习!! 废话不多说 ...
- 百度分享如何自定义分享url和内容?
百度分享默认分享的是当前页的url,但也可以在同一个页面中分享多个不同的url,仅需进行如下简单的配置. 默认的代码如下: <div id="bdshare" class=& ...
- php小算法总结一(数组重排,进制转换)
1.两个有序数组组合成一个新的有序数组 <?php $arr1=array(2,5,7,9,12); $arr2=array(3,4,6,8,10,11); function merge_sor ...
- js浏览器各种位置检测
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- cursorfilter
android.widget.CursorAdapter它首先实现了两个接口Filterable,CursorFilter.CursorFilterClient.其中Filterable接口定义了ge ...
- Noise,Error,wighted pocket Algorithm
错误衡量(Error Measure) 有两种错误计算方法: 第一种叫0/1错误,只要[预测≠目标]则认为犯错,通常用于分类:通常选择,错误比较大的值作为y˜的值 第二种叫平方错误,它衡量[预测与目标 ...
- GPS之NMEA协议20160526
NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association)为海用电子设备制定的标准格式.现在已经成为GPS导航设备统一的RTCM(Rad ...
- CMD怎样建立文件?
一.建立空文件的几种方法1.cd.>a.txtcd.表示改变当前目录为当前目录,即等于没改变:而且此命令不会有输出.>表示把命令输出写入到文件.后面跟着a.txt,就表示写入到a.txt. ...
- rails devise使用
gem 'devise'rails g devise:install Userrails g devise Userrails g devise:views