BZOJ 3887: [Usaco2015 Jan]Grass Cownoisseur tarjan + spfa
Code:
#include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 200002 using namespace std; queue<int>Q; stack<int>S; vector<int>G[maxn],V[maxn]; map<int,int>mp[maxn]; int n,m,edges,scc,id; int hd[maxn],to[maxn],nex[maxn],low[maxn],dfn[maxn],idx[maxn],vis[maxn],siz[maxn]; void addedge(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void tarjan(int u) { S.push(u); vis[u]=1, low[u]=dfn[u]=++scc; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(!vis[v]) tarjan(v), low[u]=min(low[u], low[v]); else if(vis[v]==1) low[u]=min(low[u], dfn[v]); } if(low[u]==dfn[u]) { ++id; for(;;) { int x=S.top(); S.pop(); idx[x]=id; ++siz[id]; vis[x]=-1; if(x==u) break; } } } int h1[maxn],h2[maxn], vis1[maxn],vis2[maxn],inq[maxn], ge[maxn]; void spfa1() { int s=idx[1]; Q.push(s); inq[s]=1; h1[s]=siz[s]; while(!Q.empty()) { int u=Q.front(); Q.pop(); ge[u]=1; inq[u]=0; for(int i=0;i<G[u].size();++i) { int v=G[u][i]; if(h1[v] < h1[u] + siz[v]) { h1[v] = h1[u] + siz[v]; if(!inq[v]) { Q.push(v); inq[v]=1; } } } } } void spfa2() { int s=idx[1]; Q.push(s); inq[s]=1; h2[s]=siz[s]; while(!Q.empty()) { int u=Q.front(); Q.pop(); inq[u]=0; for(int i=0;i<V[u].size();++i) { int v=V[u][i]; if(h2[v] < h2[u] + siz[v]) { h2[v] = h2[u] + siz[v]; if(!inq[v]) { Q.push(v); inq[v]=1; } } } } } int main() { // setIO("input"); scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int x,y; scanf("%d%d",&x,&y); addedge(x,y); } for(int i=1;i<=n;++i) if(!vis[i]) tarjan(i); for(int i=1;i<=n;++i) { int cur=idx[i]; for(int j=hd[i];j;j=nex[j]) { int too=idx[to[j]]; if(cur!=too && !mp[cur][too]) { mp[cur][too]=1; G[cur].push_back(too); V[too].push_back(cur); } } } spfa2(); spfa1(); int ans=siz[idx[1]]; int re=0; for(int i=1;i<=id;++i) { if(!ge[i]) continue; for(int j=0;j<V[i].size();++j) { int v=V[i][j]; if(h1[i] && h2[v])ans=max(ans, h1[i] + h2[v]-siz[idx[1]]); } } printf("%d\n",ans); return 0; }