记录编号 370254 评测结果 AAAAAAAAAA
题目名称 [SHOI 2008] 仙人掌图 最终得分 100
用户昵称 GravatarCydiater 是否通过 通过
代码语言 C++ 运行时间 0.055 s
提交时间 2017-02-13 08:17:50 内存使用 9.47 MiB
显示代码纯文本
//BZOJ 1023
//by Cydiater
//2017.2.12
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <map>
#include <cstring>
#include <string>
#include <iomanip>
#include <ctime>
#include <algorithm>
#include <cstdio>
#include <bitset>
#include <set>
#include <vector>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
#define Auto(i,node)	for(int i=LINK[node];i;i=e[i].next)
#define FILE		"bzoj_1023"
const int MAXN=2e5+5;
const int oo=0x3f3f3f3f;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,M,LINK[MAXN],len=0,dfn[MAXN],low[MAXN],dfs_clock,stack[MAXN],top=0,dccs=0,f[MAXN],ans=0;
int q[MAXN],head,tail,arr[MAXN];
vector<int>DCC[MAXN];
struct edge{
	int y,next;
}e[MAXN];
namespace solution{
	inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
	inline void Insert(int x,int y){insert(x,y);insert(y,x);}
	void Prepare(){
		N=read();M=read();
		while(M--){
			int T=read(),last=read(),now;
			while(--T){
				now=read();
				Insert(now,last);
				last=now;
			}
		}
		dccs=N;
	}
	void Tarjan(int node){
		dfn[node]=low[node]=++dfs_clock;
		stack[++top]=node;
		Auto(i,node)if(!dfn[e[i].y]){
			Tarjan(e[i].y);
			cmin(low[node],low[e[i].y]);
			if(low[e[i].y]>=dfn[node]){
				dccs++;int tmp;
				do{
					tmp=stack[top--];
					DCC[dccs].push_back(tmp);
				}while(tmp!=e[i].y);
				DCC[node].push_back(dccs);
			}
		}else cmin(low[node],dfn[e[i].y]);
	}
	void TreeDP(int node){
		f[node]=0;
		int siz=DCC[node].size();
		if(node>N){
			up(i,0,siz-1)TreeDP(DCC[node][i]);
			up(i,0,siz-1)arr[i]=f[DCC[node][i]];
			arr[siz]=0;
			up(i,siz+1,siz<<1)arr[i]=arr[i-siz-1];
			head=1;tail=0;
			up(i,0,(siz+1)/2-1){
				while(head<=tail&&arr[q[tail]]+q[tail]<arr[i]+i)tail--;
				q[++tail]=i;
			}
			int R=(siz+1)/2;
			up(L,0,siz-1){
				if(R!=siz){
					while(head<=tail&&arr[q[tail]]+q[tail]<arr[R]+R)tail--;
					q[++tail]=R;
				}
				if(q[head]==L)head++;
				if(head<=tail)cmax(ans,arr[L]+arr[q[head]]+q[head]-L);
				R++;
			}
			up(i,0,(siz+1)/2-1)cmax(f[node],f[DCC[node][i]]+i);
			up(i,(siz+1)/2,siz-1)cmax(f[node],f[DCC[node][i]]+siz-1-i);
		}else{
			int Max1=0,Max2=0;
			up(i,0,siz-1){
				TreeDP(DCC[node][i]);
				if(f[DCC[node][i]]+1>Max1){Max2=Max1;Max1=f[DCC[node][i]]+1;}
				else if(f[DCC[node][i]]+1>Max2)Max2=f[DCC[node][i]]+1;
			}
			cmax(ans,Max1+Max2);
			f[node]=Max1;
		}
	}
	void Solve(){
		Tarjan(1);
		TreeDP(1);
		cout<<ans<<endl;
	}
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	using namespace solution;
	Prepare();
	Solve();
	return 0;
}