判定二分图 & 二分图的最大匹配
1728
2022.02.13
发布于 未知归属地

一个图是二分图 等价于 这个图中不存在奇数环
可以通过染色法判断是否为二分图
匈牙利算法做二分图的最大匹配

二分图的判定 染色法

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;
int h[N], e[N], ne[N], idx;
int color[N];
int n, m;

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

bool dfs (int u, int c) {
    color[u] = c;
    for (int j = h[u]; j != -1; j = ne[j]) {
        int t = e[j];
        // dfs 染色
        if (color[t] == 0 && !dfs (t, 3 - c)) return false;
        // 染色法矛盾
        else if (color[t] == c) return false;
    }
    return true;
}

int main () {
    cin >> n >> m;
    memset (h, -1, sizeof h);
    while (m--) {
        int a, b;
        cin >> a >> b;
        add(a, b);
        add(b, a);
    }
    bool flag = true;
    for (int i = 1; i <= n; i++) {
        if (!color[i]) {
            flag = dfs (i, 1);
            if (!flag) break;
        }
    }
    if (flag) cout << "Yes";
    else cout << "No";
    return 0;
}

匈牙利算法

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;
int h[510], e[N], ne[N], idx;
int match[510];
bool st[510];
int n1, n2, m;

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

bool find(int x) {
    for (int j = h[x]; j != -1; j = ne[j]) {
        int t = e[j];
        if (!st[t]) {
            st[t] = true;
            if (match[t] == 0 || find(match[t])) {
                match[t] = x;
                return true;
            }
        }
    }
    return false;
}

int main () {
    cin >> n1 >> n2 >> m;
    memset (h, -1, sizeof h);
    while (m--) {
        int a, b;
        cin >> a >> b;
        add (a, b);
    }

    int res = 0;
    for (int i = 1; i <= n1; i++) {
        memset (st, false, sizeof st);
        if (find(i)) res++;
    }
    cout << res << endl;
    return 0;
}
评论 (0)