NC24159. [USACO 2015 Jan G]Grass Cownoisseur
描述
输入描述
The first line of input contains N and M, giving the number of fields
and the number of one-way paths (1 <= N, M <= 100,000).
The following M lines each describe a one-way cow path. Each line
contains two distinct field numbers X and Y, corresponding to a cow
path from X to Y. The same cow path will never appear more than once.
输出描述
A single line indicating the maximum number of distinct fields Bessie
can visit along a route starting and ending at field 1, given that she can
follow at most one path along this route in the wrong direction.
示例1
输入:
7 10 1 2 3 1 2 5 2 4 3 7 3 5 3 6 6 5 7 2 4 7
输出:
6
说明:
Here is an ASCII drawing of the sample input:C++14(g++5.4) 解法, 执行用时: 132ms, 内存消耗: 13588K, 提交时间: 2020-01-16 22:01:20
#include<bits/stdc++.h> using namespace std; const int MX=1e5+10; int n,m,cnt; int dfn[MX],low[MX]; int color[MX],color_num[MX]; vector<int>ve[MX],ve1[MX],ve2[MX]; bool vis[MX],f[MX]; int sum=0; stack<int>st; int ans[MX]; int max_op=0; void tarjan(int u) { dfn[u]=low[u]=++cnt; st.push(u); vis[u]=1; for(int v:ve[u]) { if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]) low[u]=min(low[u],dfn[v]); } int k; if(low[u]==dfn[u]) { sum++; do{ k=st.top();st.pop(); color[k]=sum; color_num[sum]++; vis[k]=0; }while(k!=u&&!st.empty()); } } void bfs1(int x) { queue<int>qu; qu.push(x); f[x]=1; while(!qu.empty()) { int u=qu.front();qu.pop(); for(int v:ve1[u]) { if(ans[u]+color_num[v]>ans[v]) { ans[v]=ans[u]+color_num[v]; f[v]=1; qu.push(v); } } } } int check(int x) { int S=0; for(int i:ve1[x]) { if(f[i]) S=max(S,ans[i]); } return S; } void bfs2(int x) { queue<int>q; q.push(x); while(!q.empty()) { int u=q.front();q.pop(); for(int v:ve2[u]) { if(ans[v]<ans[u]+color_num[v]) { ans[v]=ans[u]+color_num[v]; int K=check(v); if(K) max_op=max(max_op,ans[v]+K); q.push(v); } } } } int main() { // freopen("123.in","r",stdin); //1952 cin>>n>>m; for(int i=0,x,y;i<m;i++) { cin>>x>>y; ve[x].push_back(y); } for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } for(int i=1;i<=n;i++) { for(int v:ve[i]) { if(color[i]!=color[v]) { ve2[color[i]].push_back(color[v]); ve1[color[v]].push_back(color[i]); } } } ans[color[1]]=color_num[color[1]]; bfs1(color[1]); for(int i:ve1[color[1]]) { max_op=max(ans[i],max_op); } max_op+=color_num[color[1]]; bfs2(color[1]); cout<<max_op-color_num[color[1]]<<'\n'; return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 62ms, 内存消耗: 13456K, 提交时间: 2020-09-19 11:04:24
#include<bits/stdc++.h> using namespace std; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } const int maxn=5e5+10; struct E{ int next,to,val; }tu[maxn]; int head[maxn],cnt; void add(int next,int to){ tu[cnt].next=head[next]; tu[cnt].to=to; head[next]=cnt++; } stack<int>s; int n,m; int dfn[maxn],low[maxn],tim,num,bel[maxn],val[maxn],vis[maxn]; void tarjan(int x){ dfn[x]=low[x]=++tim; s.push(x); vis[x]=1; for(int i=head[x];~i;i=tu[i].next){ int u=tu[i].to; if(!dfn[u]){ tarjan(u); low[x]=min(low[x],low[u]); } else if(vis[u])low[x]=min(low[x],dfn[u]); } if(dfn[x]==low[x]){ int j; num++; do{ j=s.top(); s.pop(); vis[j]=0; bel[j]=num; val[num]++; }while(j!=x); } } struct data{ int u,v; }G[maxn]; queue<int>q; int dis[maxn]; int main(){ memset(head,-1,sizeof(head)); n=read(),m=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(); G[i].u=x,G[i].v=y; add(x,y); add(y,x+n); add(x+n,y+n); } for(int i=1;i<=2*n;i++){ if(!dfn[i])tarjan(i); } memset(tu,0,sizeof(tu)); memset(head,-1,sizeof(head)); cnt=0; for(int i=1;i<=m;i++){ int x=G[i].u,y=G[i].v; if(bel[x]==bel[y])continue; add(bel[x],bel[y]); add(bel[y],bel[x+n]); add(bel[x+n],bel[y+n]); } memset(vis,0,sizeof(vis)); q.push(bel[1]); vis[bel[1]]=1; dis[bel[1]]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];~i;i=tu[i].next){ int u=tu[i].to; if(dis[u]<dis[x]+val[u]){ dis[u]=dis[x]+val[u]; if(!vis[u]){ q.push(u); vis[u]=1; } } } } cout<<max(dis[bel[1]],dis[bel[n+1]]); return 0; }