码迷,mamicode.com
首页 > 其他好文 > 详细

luogu 2764 最小路径覆盖问题 | 最大匹配

时间:2018-03-11 17:40:55      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:lan   最小   cstring   sdi   ack   cst   eof   target   back   

luogu 2764

最小路径覆盖 = n - 最大匹配

 1 #include <cstdio>
 2 #include <string>
 3 #include <vector>
 4 #include <queue>
 5 #include <cstring>
 6 
 7 const int N = 200, INF = 0x3f3f3f3f;
 8 
 9 int read() {
10     int x = 0, f = 1;
11     char c = getchar();
12     while (!isdigit(c)) {
13         if (c == -) f = -1;
14         c = getchar();
15     }
16     while (isdigit(c)) {
17         x = (x << 3) + (x << 1) + (c ^ 48);
18         c = getchar();
19     }
20     return x * f;
21 }
22 
23 int n, m, matx[N], maty[N], dx[N], dy[N], dis, used[N];
24 std::vector<int> G[N];
25 
26 bool bfs() {
27     std::queue<int> Q; dis = INF;
28     memset(dx, -1, sizeof dx);
29     memset(dy, -1, sizeof dy);
30     for (int i = 1; i <= n; ++ i)
31         if (matx[i] == 0) Q.push(i), dx[i] = 0;
32     while (!Q.empty()) {
33         int u = Q.front(); Q.pop();
34         if (dx[u] > dis) break;
35         int size = G[u].size();
36         for (int i = 0; i < size; ++ i) {
37             int v = G[u][i];
38             if (dy[v] == -1) {
39                 dy[v] = dx[u] + 1;
40                 if (maty[v] == 0) dis = dy[v];
41                 else dx[maty[v]] = dy[v] + 1, Q.push(maty[v]); 
42             }
43         }
44     } 
45     return dis != INF;
46 }
47 
48 bool dfs(int u) {
49     int size = G[u].size();
50     for (int i = 0; i < size; ++ i) {
51         int v = G[u][i];
52         if (!used[v] && dy[v] == dx[u] + 1) {
53             used[v] = 1;
54             if (maty[v] != 0 && dy[v] == dis) continue;
55             if (maty[v] == 0 || dfs(maty[v])) {
56                 maty[v] = u, matx[u] = v;
57                 return 1;
58             }
59         }
60     }
61     return 0;
62 }
63 
64 int match() {
65     int res = 0;
66     while (bfs()) {
67         memset(used, 0, sizeof used);
68         for (int i = 1; i <= n; ++ i) {
69             if (matx[i] == 0 && dfs(i)) ++res;
70         }
71     }
72     return res;
73 }
74 
75 int main() {
76     n = read(), m = read();
77     for (int i = 1; i <= m; ++ i) {
78         int u = read(), v = read();
79         G[u].push_back(v);
80     }
81     int tmp = match();
82     for (int i = 1; i <= n; ++ i) {
83         int u = 0;
84         if (!maty[i]) u = i;
85         if (!u) continue;
86         while (u) {
87             printf("%d ", u);
88             u = matx[u];
89         } puts("");
90     }
91     printf("%d\n", n - tmp);
92     return 0;
93 }

 

luogu 2764 最小路径覆盖问题 | 最大匹配

标签:lan   最小   cstring   sdi   ack   cst   eof   target   back   

原文地址:https://www.cnblogs.com/milky-w/p/8543816.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!