1. 程式人生 > 實用技巧 >一般圖的最大匹配——帶花樹

一般圖的最大匹配——帶花樹

帶花樹演算法模板

code:

#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <functional>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include 
<fstream> #include <sstream> #include <unordered_map> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; const int N = 1e3 + 10; const int M = 1e5 + 100; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int n, m, k, x, y, t;
int e[M], ne[M], h[N], idx; int match[N]; int pre[N], col[N], f[N]; queue<int> q; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } int find(int x) { if (f[x] == x) return x; return f[x] = find(f[x]); } int mark = 0, dfn[N]; int lca(int a, int b) { ++mark; a
= find(a), b = find(b); while (dfn[a] != mark) { dfn[a] = mark; a = find(pre[match[a]]); if (b) swap(a, b); } return a; } void shrink(int a, int b, int c) { while (find(a) != c) { pre[a] = b, b = match[a]; if (col[b] == 2) col[b] = 1, q.push(b); if (find(a) == a) f[a] = c; if (find(b) == b) f[b] = c; a = pre[b]; } } bool aug(int now) { for (int i = 1; i <= n; ++i) f[i] = i, col[i] = pre[i] = 0; while (q.size()) q.pop(); q.push(now); col[now] = 1; while (q.size()) { int a = q.front(); q.pop(); for (int i = h[a]; ~i; i = ne[i]) { int j = e[i]; if (find(a) != find(j) && col[j] != 2) { if (!col[j]) { col[j] = 2, pre[j] = a; if (!match[j]) { int x = j; while (x) { int t = match[pre[x]]; match[x] = pre[x]; // swap(x, match[pre[x]]); match[pre[x]] = x; x = t; } return 1; } q.push(match[j]), col[match[j]] = 1; } else { int c = lca(a, j); shrink(a, j, c), shrink(j, a, c); } } } } return 0; } void solve() { scanf("%d%d", &n, &m); idx = 0, FT(h, -1); for (int i = 0; i < m; ++i) { int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a); } int ans = 0; FAT(match); for (int i = 1; i <= n; ++i) if (!match[i]) ans += aug(i); printf("%d\n", ans); for (int i = 1; i <= n; ++i) printf(" %d" + (i == 1), match[i]); puts(""); } int main() { #ifdef ONLINE_JUDGE #else freopen("/home/wjy/code/in.txt", "r", stdin); // freopen("/home/wjy/code/ans1.txt","w", stdout); #endif // ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T = 1; // scanf("%d", &T); // cin >> T; // time_t begin, end; // begin = clock(); while (T--) solve(); // end = clock(); // double ret = double(end - begin) / CLOCKS_PER_SEC; return 0; }