Source: Light OJ 1429 Assassin ' s Creed (II)
Test instructions: At least a few people walk the full picture can repeat the graph
Idea: If it is a DAG diagram and each point cannot be repeated then the bare minimum path overlay is now not a DAG may have loops and each point may be repeated for a graph after a ring can be indented to a point where the figure is a DAG graph another point can be repeated walk and POJ 25,941-sample preprocessing connectivity
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <stack>
using namespace Std;
const int MAXN = 1010;
int VIS[MAXN];
int Y[MAXN];
Vector <int> G[MAXN], G2[MAXN], G3[MAXN];
int n, m;
int A[MAXN][MAXN];
int PRE[MAXN];
int LOW[MAXN];
int SCCNO[MAXN];
int dfs_clock;
int scc_cnt;
Stack <int> S;
void Dfs (int u) {pre[u] = low[u] = ++dfs_clock;
S.push (U);
for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];
if (!pre[v]) {DFS (v);
Low[u] = min (Low[u], low[v]);
} else if (!sccno[v]) low[u] = min (Low[u], pre[v]);
} if (pre[u] = = Low[u]) {scc_cnt++;
while (1) {int x = S.top ();
S.pop ();
SCCNO[X] = scc_cnt;
if (x = = u) break;
}}} void Find_scc () {dfs_clock = scc_cnt = 0;
memset (sccno, 0, sizeof (SCCNO));
memset (pre, 0, sizeof (pre));
for (int i = 1; I <= n; i++) if (!pre[i]) DFS (i);
} void BFS (int u) {queue <int> Q;
memset (Vis, 0, sizeof (VIS)); ViS[u] = true;
Q.push (U); while (! Q.empty ()) {int x = Q.front ();
Q.pop ();
for (int i = 0; i < g2[x].size (); i++) {int v = g2[x][i];
if (Vis[v]) continue;
VIS[V] = true;
G[u].push_back (v);
Q.push (v);
}}}} bool Dfs2 (int u) {for (int i = 0; i < g3[u].size (); i++) {int v = g3[u][i];
if (Vis[v]) continue;
VIS[V] = true;
if (y[v] = =-1 | | DFS2 (Y[V])) {Y[v] = u;
return true;
}} return false;
} int match () {int ans = 0;
memset (y,-1, sizeof (y));
for (int i = 1; I <= scc_cnt; i++) {memset (Vis, 0, sizeof (VIS));
if (DFS2 (i)) ans++;
} return ans;
} int main () {int cas = 1;
int T;
scanf ("%d", &t);
while (t--) {scanf ("%d%d", &n, &m);
for (int i = 0; I <= N; i++) g[i].clear (), G2[i].clear (), g3[i].clear ();
while (m--) {int u, v;
scanf ("%d%d", &u, &v);
G2[u].push_back (v); } for(int i = 1; I <= n; i++)
BFS (i);
FIND_SCC ();
for (int u = 1, u <= n; u++) {for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];
if (sccno[u]! = Sccno[v]) g3[sccno[u]].push_back (Sccno[v]);
}} printf ("Case%d:%d\n", cas++, Scc_cnt-match ());
} return 0; }