# 骑士共存问题

 1 #include <bits/stdc++.h>
2 #define ID(x, y) (x - 1) * n + y
3 #define New(p) p = &tmp[++ecnt]
4
5 struct Edge {int to; Edge *nxt;} tmp[1000005], *head[40005];
6
7 int vis[40005], match[40005], ecnt = -1, n, m, tim, ans, tot;
8 int dx[] = {-1, -2, 1, 2, -1, -2, 1, 2}, dy[]={-2, -1, -2, -1, 2, 1, 2, 1};
9 bool ban[205][205];
10
11 inline void Add(int f, int to) {Edge *p; New(p); p -> to = to, p -> nxt = head[f], head[f] = p;}
12
13 bool dfs(int x) {
14     for (Edge *i = head[x]; i != NULL; i = i -> nxt) {
15         if (vis[i -> to] != tim) {
16             vis[i -> to] = tim;
17             if (!match[i -> to] || dfs(match[i -> to])) {
18                 match[i -> to] = x;
19                 return 1;
20             }
21         }
22     }
23     return 0;
24 }
25
26 signed main() {
27     scanf("%d%d", &n, &m);
28     for (int i = 1, x, y; i <= m; i++) {
29         scanf("%d%d", &x, &y);
30         ban[x][y] = 1;
31     }
32     for (int i = 1; i <= n; i++) {
33         for (int j = 1; j <= n; j++) {
34             if(ban[i][j] || ((i + j) & 1)) continue;
35             for (int k = 0; k < 8; k++) {
36                 int x = i + dx[k], y = j + dy[k];
37                 if (ban[x][y] || x < 1 || x > n || y < 1 || y > n) continue;
39             }
40         }
41     }
42     for (int i = 1; i <= n; i++) {
43         for (int j = 1; j <= n; j++) {
44             if (!ban[i][j]) {
45                 ++tim;
46                 ++tot;
47                 if (dfs(ID(i, j))) ++ans;
48             }
49         }
50     }
51     printf("%d\n", tot - ans);
52     return 0;
53 }

# 飞行员配对方案问题

 1 #include <bits/stdc++.h>
2 using namespace std;
3 #define N 1005
4
5 namespace Gekoo {
6     struct Edge {
7         int to, nxt;
8     }e[N];
9
10     pair<int, int> p[N];
11
12     int m, n, head[N], ecnt, match[N], ans, pcnt;
13     bool vis[N];
14
15     void AddEdge(int f, int to) {
16         e[++ecnt].to = to;
19     }
20
21     bool dfs(int u) {
22         for (int i = head[u]; i; i = e[i].nxt) {
23             int v = e[i].to;
24             if (!vis[v]) {
25                 vis[v] = 1;
26                 if (!match[v] || dfs(match[v])) {
27                     match[v] = u;
28                     return 1;
29                 }
30             }
31         }
32         return 0;
33     }
34
35     void QAQ() {
36         scanf("%d%d", &m, &n);
37         int i, j;
38         while (1) {
39             scanf("%d%d", &i, &j);
40             if (i == -1 && j == -1) break;
42         }
43         for (int i = 1; i <= m; i++) {
44             memset(vis, 0, sizeof(vis));
45             if(dfs(i)) ans++;
46         }
47         if (ans == 0) {
48             puts("No Solution!");
49             return ;
50         } else {
51             printf("%d\n", ans);
52             for (int i = m + 1; i <= n; i++) {
53                 if (match[i]) {
54                     p[++pcnt] = make_pair(match[i], i);
55                 }
56             }
57             sort(p + 1, p + 1 + pcnt);
58             for (int i = 1; i <= pcnt; i++) {
59                 printf("%d %d\n", p[i].first, p[i].second);
60             }
61             return ;
62         }
63     }
64 }
65
66 signed main() {
67     Gekoo::QAQ();
68     return 0;
69 }

# 方格取数问题

 1 #include <bits/stdc++.h>
2 #define id(x, y) ((x - 1) * m + y)
3
4 const int N = 500005, INF = 0x3f3f3f3f;
5 const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
6 int n, m, sum, ecnt = 1, S, T;
8 struct Edge {
9     int to, nxt, val;
10 } e[N << 5];
11
12 inline void addEdge(int f, int to, int val) {
15 }
16
17 bool bfs() {
18     memset(dep, 0, sizeof(dep));
19     dep[S] = 1;
20     std::queue<int> q;
21     q.push(S);
22     while (!q.empty()) {
23         int x = q.front();
24         q.pop();
25         for (int i = head[x], y = e[i].to; i; i = e[i].nxt, y = e[i].to) {
26             if (!dep[y] && e[i].val) {
27                 dep[y] = dep[x] + 1;
28                 if (y == T) return true;
29                 q.push(y);
30             }
31         }
32     }
33     return false;
34 }
35
36 int dfs(int x, int flow) {
37     if (x == T) return flow;
38     int las = flow, q;
39     for (int i = head[x], y = e[i].to; i; i = e[i].nxt, y = e[i].to) {
40         if (dep[y] == dep[x] + 1 && e[i].val && las) {
41             q = dfs(y, std::min(e[i].val, las));
42             if (!q) {dep[y] = 0; continue;}
43             las -= q, e[i].val -= q, e[i^1].val += q;
44         }
45     }
46     return flow - las;
47 }
48
49 int dinic() {
50     int maxflow = 0;
51     while (bfs()) maxflow += dfs(S, INF);
52     return maxflow;
53 }
54
55 signed main() {
56     scanf("%d%d", &n, &m);
57     for (int i = 1; i <= n; i++) {
58         for (int j = 1; j <= m; j++) {
59             scanf("%d", &matrix[i][j]);
60             sum += matrix[i][j];
61         }
62     }
63     S = n * m  + 1, T = S + 1;
64     for (int i = 1; i <= n; i++) {
65         for (int j = 1; j <= m; j++) {
66             if ((i + j) & 1) {
68                 for (int k = 0; k <= 3; k++) {
69                     int xx = i + dx[k], yy = j + dy[k];
70                     if (xx < 1 || yy < 1 || xx > n || yy > m) continue;
71                     addEdge(id(i, j), id(xx, yy), INF);
72                 }
73             } else {
80 }
$\Theta \omega \Theta$