BZOJ1023: [SHOI2008]cactus仙人掌图(单调队列优化DP)
来源:互联网 发布:网络新媒体概论微盘 编辑:程序博客网 时间:2024/05/20 22:36
传送门
题意:
求一颗仙人掌的直径。
题解:
DP。
首先建出图的DFS树。
因为是仙人掌图,所以每个环必定有一个dfs序最小的点,连接着若干条后向边和树边,表示环上的边或者割边。
记录
1.对于一条割边, 对答案的影响为
2.对于环边先不处理,等到dfs完所有子树后重新枚举边查找环上的儿子。(因为是在dfs树上所以连接的儿子一定是环上最后一个点。)
在多个环上分别dp。
对于环的dp:
首先,只需更新dfs树中最高点的
其次,环上的两个不是最高点的点可能对答案产生影响,就像一个环上挂了许多子树,每个子树的最长链为
#include<bits/stdc++.h>using namespace std;streambuf *ib,*ob;inline void init(){ ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); ib=cin.rdbuf();ob=cout.rdbuf();}inline int read(){ char ch=ib->sbumpc();int i=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();} while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();} return i*f;}int buf[50];inline void W(int x){ if(!x){ob->sputc('0');return;} if(x<0){ob->sputc('-');x=-x;} while(x){buf[++buf[0]]=x%10;x/=10;} while(buf[0]){ob->sputc(buf[buf[0]--]+'0');}}const int Maxn=5e4+50;int n,m,f[Maxn],dfn[Maxn],ind,low[Maxn],fa[Maxn],dep[Maxn],ans;vector<int>edge[Maxn];inline void dp(int rt,int x){ static int a[Maxn*2],que[Maxn*2],head,tail,cnt; cnt=dep[x]-dep[rt]+1; for(int i=cnt,y=x;i>=1;i--,y=fa[y])a[i]=y; int lim=cnt/2; memcpy(a+cnt+1,a+1,sizeof(int)*lim); que[head=tail=1]=1; int t=cnt;cnt+=lim; for(int i=2;i<=cnt;i++){ while(head<=tail&&que[head]<i-lim)head++; ans=max(ans,f[a[i]]+i+f[a[que[head]]]-que[head]); while(head<=tail&&f[a[que[tail]]]-que[tail]<=f[a[i]]-i)tail--; que[++tail]=i; } for(int i=2;i<=t;i++) f[rt]=max(f[rt],f[a[i]]+min(i-1,t-i+1));}inline void dfs(int now,int father){ dep[now]=dep[father]+1;low[now]=dfn[now]=++ind;fa[now]=father; for(int e=edge[now].size()-1;e>=0;e--) { int v=edge[now][e]; if(v==father)continue; if(!dfn[v]){ dfs(v,now); low[now]=min(low[now],low[v]); } else low[now]=min(low[now],dfn[v]); if(dfn[now]<low[v]){ ans=max(ans,f[now]+f[v]+1); f[now]=max(f[now],f[v]+1); } } for(int e=edge[now].size()-1;e>=0;e--) { int v=edge[now][e]; if(v==father)continue; if(fa[v]!=now&&dfn[v]>dfn[now]) dp(now,v); }}int main(){ init();n=read(),m=read(); for(int i=1;i<=m;i++) { int k=read(),a=read(); for(int i=2;i<=k;i++) { int b=read(); edge[a].push_back(b); edge[b].push_back(a); a=b; } } dfs(1,0); W(ans);ob->sputc('\n');}
阅读全文
0 0
- BZOJ1023: [SHOI2008]cactus仙人掌图(单调队列优化DP)
- [BZOJ1023] [SHOI2008]cactus仙人掌图 && 仙人掌DP+单调队列
- [BZOJ1023][SHOI2008][仙人掌直径][队列优化DP]cactus仙人掌图
- bzoj1023 [SHOI2008]cactus仙人掌图 树形DP+单调队列
- [BZOJ1023][SHOI2008[Cactus仙人掌]][Tarjan+单调队列+树形DP]
- 【SHOI2008】【BZOJ1023】cactus仙人掌图
- 【bzoj1023】[SHOI2008]cactus仙人掌图
- bzoj1023: [SHOI2008]cactus仙人掌图
- BZOJ1023 [SHOI2008]cactus仙人掌图
- bzoj1023: [SHOI2008]cactus仙人掌图
- bzoj1023 [SHOI2008]cactus仙人掌图
- BZOJ1023: [SHOI2008]cactus仙人掌图
- [仙人掌直径 单调队列 DP] BZOJ 1023 [SHOI2008]cactus仙人掌图
- [SHOI2008]cactus仙人掌图 (tarjan + dp)
- bzoj1023 cactus仙人掌图
- [BZOJ1023]静态仙人掌 Tarjan+dp+单调队列
- 【DP】 BZOJ 1023: [SHOI2008]cactus仙人掌图
- BZOJ 1023 SHOI2008 cactus仙人掌图 仙人掌DP
- hibernate一级缓存与快照
- Lua 基本语法
- Scrapy爬虫入门教程 安装和基本使用
- php使用Url读取文件的内容及file_get_contents用法
- php ip2long 出现负数原因及解决方法
- BZOJ1023: [SHOI2008]cactus仙人掌图(单调队列优化DP)
- 补提交卡
- 安装Scala-2.11.7——集群学习日记
- 关于DataGridView 控件的使用
- Linux中if语句中-的意义
- 山寨币交易平台开发完成后源码如何链接到公网当中
- SQL Dialect is Not Configured (Pycharm)
- 高级算法日记8:图(1)
- 【转】各大Android应用发布市场