1. 程式人生 > >BZOJ P3887 [USACO15JAN]草鑑定Grass Cownoisseur 【Tarjan縮點】【DAG最長路】

BZOJ P3887 [USACO15JAN]草鑑定Grass Cownoisseur 【Tarjan縮點】【DAG最長路】

差不多是板子了:

#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e5+5;
const ll Inf=1e18;

ll n,m,ans;
ll top,tim,scc,vis[N],dfn[N],low[N],bel[N],size[N],stack[N];


struct node {
	ll vis[N],dis[N];
	ll cnt,from[N],to[N],nxt[N],head[N];

	void ins(ll x,ll y) {
		from[++cnt]=x;to[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
	}
	
	void spfa() {
		queue<ll>q;
		rep(i,1,n) dis[i]=-Inf;
		q.push(bel[1]);vis[bel[1]]=1;dis[bel[1]]=0;
		
		while(q.size()) {
			ll x=q.front();q.pop();vis[x]=0;
			for(ll i=head[x];i;i=nxt[i]) {
				ll y=to[i],z=size[y];
				if(dis[x]+z>dis[y]) {
					dis[y]=dis[x]+z;
					if(vis[y]==0) {
						vis[y]=1;q.push(y);
					}
				}
			}
		}
	}
};

node G1,G2,G3;

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

void tarjan(ll x) {
	dfn[x]=low[x]=++tim;vis[x]=1;stack[++top]=x;
	for(ll i=G1.head[x];i;i=G1.nxt[i]) {
		ll y=G1.to[i];
		if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
		else if(vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]!=low[x]) return ;
	
	scc++;
	
	while(true) {
		ll y=stack[top--];
		vis[y]=0;bel[y]=scc;size[scc]++;
		if(x==y) return ;
	}
}

void File() {
	freopen("taste.in","r",stdin);
	freopen("taste.out","w",stdout);
}

int main() {
//	File();
	
	n=read(),m=read();
	
	rep(i,1,m) {
		ll x=read(),y=read();G1.ins(x,y);
	}

	rep(i,1,n) if(!dfn[i]) tarjan(i);
	
	rep(i,1,m) {
		ll x=G1.from[i],y=G1.to[i];
		
		if(bel[x]!=bel[y]) G2.ins(bel[x],bel[y]),G3.ins(bel[y],bel[x]);
	}
	
	G2.spfa();
	G3.spfa();
	
	rep(i,1,G2.cnt) {
		ll x=G2.to[i],y=G2.from[i];
		
		ans=max(ans,G2.dis[x]+G3.dis[y]+size[bel[1]]);
	}

	printf("%lld",ans);

	return 0;
}