For an edge x->y, if x cannot reach y after it is removed, it is required.
First, the topological order is sorted out and then the first key is followed by the topological order of the end point, and the starting topological order is the second keyword from small to large plus edge.
For each point, maintain a bitset that represents the point at which you are currently able to reach yourself.
Time Complexity $o (\frac{nm}{32}) $.
#include <cstdio> #include <bitset> #include <algorithm>using namespace Std;typedef pair<int,int >p;const int N=1502,m=10002;int N,m,i,j,x,y,d[n],g[n],g2[n],v[m],v2[m],nxt[m],nxt2[m],ed,h,t,q[n],ans;bitset <N>f[N]; P b[m];inline void Add (int x,int y) {d[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void add2 (int x,int y) {v2[++ed]=y;nxt2[ed]=g2[x];g2[x]=ed;} int main () { scanf ("%d%d", &n,&m); for (i=1;i<=n;i++) f[i][i]=1; while (m--) scanf ("%d%d", &x,&y), add (x, y); for (ed=0,i=h=1;i<=n;i++) if (!d[i]) q[++t]=i; while (h<=t) for (I=G[X=Q[H++]];I;ADD2 (v[i],x), i=nxt[i]) if (! ( --d[v[i]]) q[++t]=v[i]; for (i=1;i<=n;i++) for (J=g2[x=q[i]];j;f[x]|=f[v2[j]],j=nxt2[j]) if (!f[x][v2[j]]) b[++ans]=p (v2[j],x); Sort (b+1,b+ans+1); For (printf ("%d\n", ans), i=1;i<=ans;i++) printf ("%d%d\n", b[i].first,b[i].second); return 0;}
BZOJ3355: [Usaco2004 Jan] ordered cow