好难不会做TAT。
只好Orz各路神犇的题解。
搞了一个小时,终于乱搞出来了。
大概就是Tarjan+树形DP+环上单调队列DP+乱七八糟的讨论。
脑子有点糊了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=50000+5; inline int read(){ int x=0;char ch; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } struct Edge{int to,next;}e[N*20]; int f[N],ans,que[N<<1],cir[N<<1],head[N],cnt,fa[N],dep[N],lowlink[N],pre[N],dfs_clock; void ins(int u,int v){ e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt; } void dp(int u,int root){ int n=dep[u]-dep[root]+1; for(int i=u;i!=root;i=fa[i]) cir[n--]=f[i]; cir[n]=f[root]; n=dep[u]-dep[root]+1; for(int i=1;i<=n;i++)cir[i+n]=cir[i]; que[1]=1;int head=1,rear=1; for(int i=2;i<=n*2;i++){ while(head<=rear&&i-que[head]>n/2)head++; ans=max(ans,i-que[head]+cir[i]+cir[que[head]]); while(head<=rear&&cir[que[rear]]-que[rear]<=cir[i]-i)rear--; que[++rear]=i; } for(int i=2;i<=n;i++) f[root]=max(f[root],cir[i]+min(i-1,n-i+1)); } void tarjan(int u){ lowlink[u]=pre[u]=++dfs_clock; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa[u])continue; if(!pre[v]){ fa[v]=u;dep[v]=dep[u]+1; tarjan(v); lowlink[u]=min(lowlink[u],lowlink[v]); }else lowlink[u]=min(lowlink[u],pre[v]); if(pre[u]<lowlink[v]){ ans=max(ans,f[u]+f[v]+1); f[u]=max(f[u],f[v]+1); } } for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(fa[v]!=u&&pre[u]<pre[v]) dp(v,u); } } int main(){ int n,m;n=read();m=read(); int k,u,v; while(m--){ k=read();u=read();k--; while(k--){ v=read();ins(u,v);ins(v,u); u=v; } } tarjan(1); printf("%d",ans); return 0; }