[仙人掌直径 单调队列 DP] BZOJ 1023 [SHOI2008]cactus仙人掌图

来源:互联网 发布:酷狗音乐mac版 编辑:程序博客网 时间:2024/05/10 08:01

题解:http://z55250825.blog.163.com/blog/static/150230809201412793151890/

http://hzwer.com/4645.html


#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=50005;const int M=200005;struct edge{int u,v,next;};edge G[M];int head[N],inum=1;inline void add(int u,int v,int p){G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}int n,m,ans;int clk,pre[N],low[N];int fat[N],depth[N];int f[N];int a[N<<1],Q[N<<1],l,r;void dp(int rt,int x){int pnt=depth[x]-depth[rt]+1;for(int i=x;i!=rt;i=fat[i]) a[pnt--]=f[i]; a[pnt]=f[rt];pnt=depth[x]-depth[rt]+1;for(int i=1;i<=pnt;i++) a[i+pnt]=a[i];l=1; r=0;for(int i=1;i<=pnt+pnt;i++){while(l<=r && i-Q[l]>pnt/2) l++;if (l<=r) 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;}for(int i=2;i<=pnt;i++)f[rt]=max(f[rt],a[i]+min(i-1,pnt-i+1));}#define V G[p].vvoid dfs(int u,int fa){pre[u]=low[u]=++clk; depth[u]=depth[fa]+1; fat[u]=fa;for (int p=head[u];p;p=G[p].next)if (V!=fa){if (!pre[V]){dfs(V,u);low[u]=min(low[u],low[V]);}elselow[u]=min(low[u],pre[V]);if (low[V]>pre[u]){ans=max(ans,f[u]+f[V]+1);f[u]=max(f[u],f[V]+1);}}for (int p=head[u];p;p=G[p].next)if (u!=fat[V] && pre[u]<pre[V])dp(u,V);}int main(){int k,iu,iv;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(m);for (int i=1;i<=m;i++){read(k); read(iu);for (int j=2;j<=k;j++)read(iv),add(iu,iv,++inum),add(iv,iu,++inum),iu=iv;}dfs(1,0);printf("%d\n",ans);return 0;}


0 0
原创粉丝点击