# 二分图

## ——及其相关

DAG最小路径点覆盖的边数 = n - 转化后二分图最大匹配的边数

DAG最小路径可重复点覆盖的边数 = 传递闭包后的最小路径点覆盖的边数

 1 #include <cstdio>
2 #include <cstring>
3
4 const int N = 1010;
5
6 struct Edge {
7     int nex, v;
8 }edge[N * N * 2]; int top;
9
10 int mat[N << 1], e[N << 1];
11 bool vis[N << 1];
12
13 inline void add(int x, int y) {
14     ++top;
15     edge[top].nex = e[x];
16     edge[top].v = y;
17     e[x] = top;
18     return;
19 }
20
21 bool DFS(int x) {
22     for(int i = e[x]; i; i = edge[i].nex) {
23         int y = edge[i].v;
24         if(!vis[y]) {
25             vis[y] = 1;
26             if(!mat[y] || DFS(mat[y])) {
27                 mat[y] = x;
28                 return 1;
29             }
30         }
31     }
32     return 0;
33 }
34
35 int main() {
36     int n, m, e;
37     scanf("%d%d%d", &n, &m, &e);
38     for(int i = 1, x, y; i <= e; i++) {
39         scanf("%d%d", &x, &y);
40         if(x > n || y > m) {
41             continue;
42         }
45     }
46     int ans = 0;
47     for(int i = 1; i <= n; i++) {
48         memset(vis, 0, sizeof(vis));
49         ans += DFS(i);
50     }
51     printf("%d", ans);
52     return 0;
53 }

  1 #include <queue>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5
6 const int N = 1010, INF = 0x7f7f7f7f;
7
8 struct Edge {
9     int nex, v, c;
10 }edge[(N + 1) * N * 2]; int top = 1;
11
12 int d[N << 1], e[N << 1];
13 bool vis[N << 1];
14
15 inline void add(int x, int y, int z) {
16     ++top;
17     edge[top].nex = e[x];
18     edge[top].v = y;
19     edge[top].c = z;
20     e[x] = top;
21     ++top;
22     edge[top].nex = e[y];
23     edge[top].c = 0;
24     edge[top].v = x;
25     e[y] = top;
26     return;
27 }
28
29 inline bool BFS(int s, int t) {
30     std::queue<int> Q;
31     Q.push(s);
32     memset(d, 0, sizeof(d));
33     d[s] = 1;
34     while(!Q.empty()) {
35         int x = Q.front();
36         Q.pop();
37         for(int i = e[x]; i; i = edge[i].nex) {
38             int y = edge[i].v;
39             if(d[y] || !edge[i].c) {
40                 continue;
41             }
42             d[y] = d[x] + 1;
43             Q.push(y);
44         }
45     }
46     return d[t];
47 }
48
49 int DFS(int x, int t, int maxF) {
50     if(x == t) {
51         return maxF;
52     }
53     int ans = 0;
54     for(int i = e[x]; i; i = edge[i].nex) {
55         int y = edge[i].v;
56         if(!edge[i].c || d[x] + 1 != d[y]) {
57             continue;
58         }
59         int temp = DFS(y, t, std::min(edge[i].c, maxF - ans));
60         if(!temp) {
61             d[y] = 0;
62             continue;
63         }
64         ans += temp;
65         edge[i].c -= temp;
66         edge[i ^ 1].c += temp;
67         if(ans == maxF) {
68             break;
69         }
70     }
71     return ans;
72 }
73
74 inline int solve(int s, int t) {
75     int ans = 0;
76     while(BFS(s, t)) {
77         ans += DFS(s, t, INF);
78     }
79     return ans;
80 }
81
82 int main() {
83     int n, m, e;
84     scanf("%d%d%d", &n, &m, &e);
85     for(int i = 1, x, y; i <= e; i++) {
86         scanf("%d%d", &x, &y);
87         if(x > n || y > m) {
88             continue;
89         }
90         add(x, y + n, 1);
91     }
92     int S = m + n + 1;
93     int T = S + 1;
94     for(int i = 1; i <= n; i++) {
96     }
97     for(int i = 1; i <= m; i++) {
98         add(n + i, T, 1);
99     }
100     int ans = solve(S, T);
101     printf("%d", ans);
102     return 0;
103 }
Dinic 洛谷P3386 AC代码

 1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 const int N = 10010;
6
7 int mat[N << 1], a[N], b[N];
8 bool vis[N << 1];
9
10 inline bool DFS(int x) {
11     int y = a[x];
12     if(!vis[y]) {
13         vis[y] = 1;
14         if(!mat[y] || DFS(mat[y])) {
15             mat[y] = x;
16             return 1;
17         }
18     }
19     if(a[x] == b[x]) {
20         return 0;
21     }
22     y = b[x];
23     if(!vis[y]) {
24         vis[y] = 1;
25         if(!mat[y] || DFS(mat[y])) {
26             mat[y] = x;
27             return 1;
28         }
29     }
30     return 0;
31 }
32
33 int main() {
34     int n, x, y, z;
35     scanf("%d", &n);
36     for(int i = 1; i <= n; i++) {
37         scanf("%d", &x);
38         y = i + x;
39         z = i - x;
40         while(y > n) {
41             y -= n;
42         }
43         while(z <= 0) {
44             z += n;
45         }
46         a[i] = std::min(y, z) + n;
47         b[i] = std::max(y, z) + n;
48     }
49     for(int i = n; i >= 1; i--) {
50         memset(vis, 0, sizeof(vis));
51         if(!DFS(i)) {
53             return 0;
54         }
55     }
56     for(int i = 1; i <= n; i++) {
57         if(mat[a[i]] == i) {
58             printf("%d ", a[i] - n - 1);
59         }
60         else {
61             printf("%d ", b[i] - n - 1);
62         }
63     }
64     return 0;
65 }
AC代码

  1 #include <queue>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5
6 const int N = 110, INF = 0x7f7f7f7f;
7
8 struct Edge {
9     int nex, v, c;
10 }edge[(N + 1) * N * 2]; int top = 1;
11
12 int d[N << 1], e[N << 1];
13
14 inline void add(int x, int y, int z) {
15     ++top;
16     edge[top].nex = e[x];
17     edge[top].v = y;
18     edge[top].c = z;
19     e[x] = top;
20     ++top;
21     edge[top].nex = e[y];
22     edge[top].c = 0;
23     edge[top].v = x;
24     e[y] = top;
25     return;
26 }
27
28 inline bool BFS(int s, int t) {
29     std::queue<int> Q;
30     Q.push(s);
31     memset(d, 0, sizeof(d));
32     d[s] = 1;
33     while(!Q.empty()) {
34         int x = Q.front();
35         Q.pop();
36         for(int i = e[x]; i; i = edge[i].nex) {
37             int y = edge[i].v;
38             if(d[y] || !edge[i].c) {
39                 continue;
40             }
41             d[y] = d[x] + 1;
42             Q.push(y);
43         }
44     }
45     return d[t];
46 }
47
48 int DFS(int x, int t, int maxF) {
49     if(x == t) {
50         return maxF;
51     }
52     int ans = 0;
53     for(int i = e[x]; i; i = edge[i].nex) {
54         int y = edge[i].v;
55         if(!edge[i].c || d[x] + 1 != d[y]) {
56             continue;
57         }
58         int temp = DFS(y, t, std::min(edge[i].c, maxF - ans));
59         if(!temp) {
60             d[y] = 0;
61             continue;
62         }
63         ans += temp;
64         edge[i].c -= temp;
65         edge[i ^ 1].c += temp;
66         if(ans == maxF) {
67             break;
68         }
69     }
70     return ans;
71 }
72
73 inline int solve(int s, int t) {
74     int ans = 0;
75     while(BFS(s, t)) {
76         ans += DFS(s, t, INF);
77     }
78     return ans;
79 }
80
81 int n;
82 void work() {
83     int m, k;
84     top = 1;
85     memset(e, 0, sizeof(e));
86     scanf("%d%d", &m, &k);
87     for(int i = 1, x, y, z; i <= k; i++) {
88         scanf("%d%d%d", &z, &x, &y);
89         if(!x || !y) {
90             continue;
91         }
92         add(x, y + n - 1, 1);
93     }
94     int S = m + n - 1;
95     int T = S + 1;
96     for(int i = 1; i < n; i++) {
98     }
99     for(int i = 1; i < m; i++) {
100         add(n + i - 1, T, 1);
101     }
102     int ans = solve(S, T);
103     printf("%d\n", ans);
104     return;
105 }
106
107 int main() {
108     while(scanf("%d", &n)) {
109         if(!n) {
110             return 0;
111         }
112         work();
113     }
114 }
AC代码

posted @ 2018-09-27 16:05  garage  阅读(...)  评论(...编辑  收藏