1
+ /*
2
+ Author: Le Trong Dat
3
+ Idea:
4
+ * W(C, R, T) = True/False. True if Cop wins and False if Cop loses.
5
+ * W(i, i, 0/1) = true because Cop already won.
6
+ * W(C, R, 0) = True <=> Exists one state W(X, R, 1) = true.
7
+ * W(C, R, 1) = true <=> All states W(C, X, 0) = true.
8
+ */
9
+ #include " coprobber.h"
10
+ #include < bits/stdc++.h>
11
+ const int maxN = 500 ;
12
+ using namespace std ;
13
+ #define forn (i, a, b ) for (int i=a; i<=b; ++i)
14
+ #define repn (i, a, b ) for (int i=a; i <b; ++i)
15
+
16
+ int cur;
17
+ int mov[maxN][maxN], deg[maxN][maxN];
18
+ int W[maxN][maxN][2 ];
19
+ int start (int N, bool A[maxN][maxN]) {
20
+ queue < tuple < int , int , int > > q;
21
+ repn (i, 0 , N) repn (j, 0 , N) repn (k, 0 , N) deg[i][j] += A[j][k];
22
+ repn (i, 0 , N) forn (turn, 0 , 1 ) {
23
+ W[i][i][turn] = 1 ;
24
+ q.push ({i, i, turn});
25
+ }
26
+ while (q.size ()) {
27
+ int c, r, t;
28
+ tie (c, r, t) = q.front ();
29
+ q.pop ();
30
+ repn (i, 0 , N) {
31
+ if (t) {
32
+ if ( (A[c][i] || i == c) && !W[i][r][0 ]) {
33
+ mov[i][r] = c;
34
+ W[i][r][0 ] = true ;
35
+ q.push ({i, r, 0 });
36
+ }
37
+ continue ;
38
+ }
39
+ if (A[r][i] && !W[c][i][1 ] && --deg[c][i] < 1 ) {
40
+ W[c][i][1 ] = true ;
41
+ q.push ({c, i, 1 });
42
+ }
43
+ }
44
+ }
45
+ bool ok = true ;
46
+ repn (i, 0 , N) ok &= W[0 ][i][0 ];
47
+ return (ok ? 0 : -1 );
48
+ }
49
+ int nextMove (int R) {
50
+ return cur = mov[cur][R];
51
+ }
0 commit comments