BZOJ P3887 [USACO15JAN]草鑑定Grass Cownoisseur 【Tarjan縮點】【DAG最長路】
阿新 • • 發佈:2018-12-11
差不多是板子了:
#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; }