bzoj1023: [SHOI2008]cactus仙人掌图
求仙人掌的直径。
求一遍边双,建立圆方树,然后在树上dp;
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
const int N=100007;
typedef long long LL;
using namespace std;
int n,m;
template<typename T> void read(T &x) {
T f=1; x=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt=1,fir[N],nxt[N<<1],to[N<<1];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}
int ec,fi[N],nx[N],tt[N];
void add_edge(int u,int v) {
nx[++ec]=fi[u]; fi[u]=ec; tt[ec]=v;
}
int tot,dfn[N],low[N],dfs_clock,sta[N],top;
void tarjan(int x,int f) {
dfn[x]=low[x]=++dfs_clock;
sta[++top]=x;
for(int i=fir[x];i;i=nxt[i]) {
int y=to[i];
if(!dfn[y]) {
tarjan(y,i^1);
if(low[y]>dfn[x]) add_edge(x,y),top--;
low[x]=min(low[x],low[y]);
if(low[y]==dfn[x]) {
add_edge(x,++tot);
while(top) {
int z=sta[top--];
add_edge(tot,z);
if(z==y) break;
}
}
}
else if(i^f) low[x]=min(low[x],dfn[y]);
}
}
int f[N],que[N],ql,qr,tmp[N],tp,ans;
void dfs(int x) {
for(int i=fi[x];i;i=nx[i])
dfs(tt[i]);
if(x<=n) {
int cd=0;
for(int i=fi[x];i;i=nx[i]) {
cd=max(cd,f[tt[i]]+1);
if(cd>f[x]) swap(cd,f[x]);
}
ans=max(ans,f[x]+cd);
}
else {
ql=1; qr=0; tp=1;
for(int i=fi[x];i;i=nx[i]) tmp[tp++]=tt[i];
for(int i=0;i<tp;i++) tmp[tp+i]=tmp[i];
for(int i=1;i<=(tp>>1)+tp;i++) {
while(ql<=qr&&(i-que[ql])*2>tp) ql++;
if(i>(tp>>1)) ans=max(ans,f[tmp[i]]+f[tmp[que[ql]]]+i-que[ql]);
while(ql<=qr&&f[tmp[que[qr]]]-que[qr]<=f[tmp[i]]-i) qr--;
que[++qr]=i;
}
for(int i=1;i<=(tp>>1);i++) f[x]=max(f[x],f[tmp[i]]+i-1);
for(int i=(tp>>1)+1;i<tp;i++) f[x]=max(f[x],f[tmp[i]]+tp-i-1);
}
}
int main() {
read(n); read(m); tot=n;
while(m--) {
int k,x,y;
read(k); read(x);
for(int i=k-1;i;i--) {
read(y); add(x,y); x=y;
}
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
dfs(1);
printf("%d\n",ans);
return 0;
}
/*
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 8
10 1
10 1 2 3 4 5 6 7 8 9 10
*/