Source: Light OJ 1406 Assassin ' s Creed
Test instructions: There is a way to send the fewest people through all the cities and everyone can't walk where others walk.
Idea: the least of the people can walk the complete graph is obviously the smallest path coverage problem there may be a ring so to shrink point but look at the sample and find that a strong connected component may be split n Max 15 so state compression
Divide the entire image into a sub-state each child state indent to find the minimum path coverage this solves the problem of a strongly connected component split. The final state compression DP solves the optimal value
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <stack&
Gt
using namespace Std;
const int MAXN = 16;
Vector <int> G[MAXN], G2[MAXN];
int dp[1<<maxn];
int PRE[MAXN], LOW[MAXN], SCCNO[MAXN];
int clock, scc_cnt;
int n, m;
Stack <int> S;
int A[MAXN][MAXN];
int B[MAXN][MAXN];
void Dfs (int u, int x) {Pre[u] = low[u] = ++clock;
S.push (U);
for (int i = 0; i < g[u].size (); i++) {int v = g[u][i]; if (! (
x& (1<<V))) continue;
if (!pre[v]) {DFS (v, x);
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;
}}} int find_scc (int x) {memset (sccno, 0, sizeof (SCCNO));
memset (pre, 0, sizeof (pre));
scc_cnt = 0, clock = 0; for (int i = 0; i < n; i++) {if (x& (1<<i) &&!pre[i]) DFS (i, x);
} return scc_cnt;
} int Y[MAXN];
BOOL VIS[MAXN];
BOOL Xyl (int u) {for (int i = 0; i < g2[u].size (); i++) {int v = g2[u][i];
if (Vis[v]) continue;
VIS[V] = true;
if (y[v] = =-1 | | xyl (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, false, sizeof (VIS));
if (Xyl (i)) ans++;
} return Scc_cnt-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 ();
memset (A, 0, sizeof (a));
while (m--) {int u, v;
scanf ("%d%d", &u, &v);
u--;
v--;
G[u].push_back (v);
A[U][V] = 1;
} Dp[0] = 0;
Puts ("SDF");
for (int i = 1; i < (1<<n); i++) {//memset (b, 0, sizeof (b));
FIND_SCC (i);
for (int j = 0; J <= N; j + +) G2[j].clear ();
for (int j = 0; J < N; j + +) for (int k = 0; k < n; k++)if (A[j][k] && sccno[j] && sccno[k] && sccno[j]! = Sccno[k]) g2[sccno[j]].push_back (Sccno[k])
;
Dp[i] = match ();
}//puts ("SDF"); for (int s = 1; s < (1<<n); s++) {for (int i = s; i; i = s& (i-1)) {Dp[s] = min (Dp[s], Dp[s^i] + D
P[i]);
}} printf ("Case%d:%d\n", cas++, dp[(1<<n)-1]);
} return 0;
}