【BZOJ1023】仙人掌图(仙人掌,动态规划)
【BZOJ1023】仙人掌图(仙人掌,动态规划)
题面
BZOJ
求仙人掌的直径(两点之间最短路径最大值)
题解
一开始看错题了,以为是求仙人掌中的最长路径。。。
后来发现看错题了一下就改过来了。。
首先和普通的仙人掌\(dp\)是一样的,
对于没有问题的圆圆边,直接做最长链的转移(同时更新\(ans\))
然后对于一个环,把它拎出来单独考虑
首先要对于这个环,计算能够贡献的答案,
然后再用环上的值更新环的最顶点
先考虑怎么更新,这个直接拿环上的点的\(dp\)值,再计算一下这两点之间的最短路(深度差和环大小减深度差的较小值),相加去更新\(dp\)值。
然后考虑一下如何贡献答案,
要求的相当于是\(max(f[i]+f[j]+dist(i,j))\)
而\(dist(i,j)=min(abs(dep[i]-dep[j]),circle\_size-abs(dep[i]-dep[j]))\)
发现维护一个单调队列,按照深度依次进栈,
这样子距离直接可以用深度做差,没有了绝对值
因为可以通过返祖边回去,因此把所有点按照顺序进两次队就可以了
第二次进队的时候给深度加上一个环大小再进队
然后如何保证是环上的最短路?
如果两个深度差已经大于环大小的一半了,那么最短路就不是这一条了
所以直接弹走队首就行了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 55555
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Line{int v,next;}e[MAX<<3];
int h[MAX],cnt=1,n,m;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int f[MAX],ans=1,fa[MAX],dep[MAX],dfn[MAX],low[MAX],tim;
int H,T,Q1[MAX<<1],Q[MAX<<1];
void dp(int u,int y)
{
	int t=0;
	for(int i=y;i!=u;i=fa[i])Q1[++t]=i;Q1[++t]=u;
	reverse(&Q1[1],&Q1[t+1]);
	for(int i=1;i<=t;++i)Q1[i+t]=Q1[i];
	H=1;T=0;
	for(int i=1;i<=t+t;++i)
	{
		while(H<=T&&i-Q[H]>t/2)++H;
		if(H<=T)ans=max(ans,f[Q1[i]]+f[Q1[Q[H]]]+i-Q[H]);
		while(H<=T&&f[Q1[i]]-i>f[Q1[Q[T]]]-Q[T])--T;
		Q[++T]=i;
	}
	for(int i=y;i!=u;i=fa[i])
		f[u]=max(f[u],f[i]+min(dep[i]-dep[u],1+dep[y]-dep[i]));
}
void dfs(int u,int ff)
{
	fa[u]=ff;dfn[u]=low[u]=++tim;dep[u]=dep[ff]+1;
	for(int i=h[u];i;i=e[i].next)
	{
		int v=e[i].v;
		if(!dfn[v])dfs(v,u),low[u]=min(low[u],low[v]);
		else if(v!=ff)low[u]=min(low[u],dfn[v]);
		if(low[v]>dfn[u])
			ans=max(ans,f[u]+f[v]+1),f[u]=max(f[u],f[v]+1);
	}
	for(int i=h[u];i;i=e[i].next)
		if(fa[e[i].v]!=u&&dfn[u]<dfn[e[i].v])
			dp(u,e[i].v);
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=m;++i)
	{
		int K=read(),a=read();
		for(int j=1;j<K;++j)
		{
			int b=read();
			Add(a,b);Add(b,a);
			a=b;
		}
	}
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}
												
											【BZOJ1023】仙人掌图(仙人掌,动态规划)的更多相关文章
- BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)
		
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3467 Solved: 1438[Submit][Status][Discuss] Descripti ...
 - BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌)
		
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...
 - BZOJ1023 SHOI2008 仙人掌图 仙人掌、单调队列
		
传送门 求仙人掌的直径,可以由求树的直径进行拓展,只需要在环上特殊判断. 沿用求树的直径的DP,对于一条不在任何环内的边,直接像树的直径一样转移,然后考虑环的影响. 设环长为\(cir\),在\(df ...
 - 【bzoj1023】仙人掌图
		
[bzoj1023]仙人掌图 题意 给一棵仙人掌,求直径. \(n\leq 100000\) 分析 分析1:[Tarjan]+[环处理+单调队列优化线性dp]+[树形dp] 分开两种情况处理: ①环: ...
 - 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]仙人掌图——题解
		
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple ...
 - BZOJ1023[SHOI2008]cactus仙人掌图  【仙人掌DP】
		
题目 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌 图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路. 举例来说 ...
 - 仙人掌图判定及求直径HDU3594 BZOJ1023
		
https://wenku.baidu.com/view/ce296043192e45361066f575.html //仙人掌图基础知识3个判定条件 http://blog.csdn.net/y ...
 
随机推荐
- 使用PHPExcel导出数据库表结构及内容
			
导出表结构: mysql> desc user ; +----------+--------------+------+-----+---------------------+--------- ...
 - 【问题解决方案】之 jmeter启动报错:Not able to find Java executable or version. Please check your Java installation
			
故事发生在云计算实验课上-- ** 故事发生在云计算实验课上-- Step 1 在Xshell中登录自己的cloud虚拟机后,<sudo su ->切换到root用户 Step 2 < ...
 - 从Mongo导出数据库到Excel
			
在MongoDB的安装目录的bin文件夹下打开命令行: ./mongoexport -d kugou_db -c songs -f rank,singer,song,time --type=csv - ...
 - laravel log改为时间格式
			
1 providers新建文件 LogRotateServiceProvider.php <?php namespace App\Providers; use Monolog\Formatter ...
 - [转帖]浅谈程序中的text段、data段和bss段
			
作者:百问科技链接:https://zhuanlan.zhihu.com/p/28659560来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一般情况,一个程序本质上都 ...
 - Vagrant系列(二)----Vagrant的配置文件Vagrantfile详解
			
一.简介 在我们的工作目录下有一个Vagrantfile文件,里面包含有大量的配置信息,通过它可以定义虚拟机的各种配置,如网络.内存.主机名等,主要包括三个方面的配置,虚拟机的配置.SSH配置.Vag ...
 - embed标签的flash层级太高问题
			
因为客户要求,项目得兼容IE的兼容模式 页面到了flash都会遮挡底部悬浮的导航. 改变浮动窗口和embed的层级还是不可以.应该不是层级的关系. 最后百度解决方案:在embed标签内添加了wmode ...
 - Eclipse导入工程后出现中文乱码
			
Eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的.一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果该工程的编码方式与eclipse中设置的编码方式不同 ...
 - Spring boot+ logback环境下,日志存放路径未定义的问题
			
日志路径未定义 环境:Spring boot + logback 配置文件: <configuration> <springProfile name="dev"& ...
 - 如何在TypeScript中使用第三方JavaScript框架
			
一.安装typings 使用npm全局安装typings :npm install -g typings 安装成功. 二,搜索资源,支持模糊搜索:typings search base64 三.安装t ...