Đồ thị hai phía

Bài toán tìm cặp ghép cực đại


#include <bits/stdc++.h>
using namespace std;

#define MAX_NUT 114514
#define MAX_CANH 1919810

long long so_nut_A, so_nut_B, so_canh;
long long danh_dau[501], ket_noi[MAX_NUT], ket_qua;

typedef pair<long long, long long> Cap;

map<Cap, bool> canh_ton_tai;

bool tim_ket_noi(long long nut) {
    for (int i = 1; i <= so_nut_B; ++i) {
        if (danh_dau[i] || !canh_ton_tai[make_pair(nut, i)]) continue;
        danh_dau[i] = 1;
        if (!ket_noi[i] || tim_ket_noi(ket_noi[i])) {
            ket_noi[i] = nut;
            return true;
        }
    }
    return false;
}

int main() {
    cin >> so_nut_A >> so_nut_B >> so_canh;
    for (int i = 0; i < so_canh; ++i) {
        long long a, b;
        cin >> a >> b;
        if (canh_ton_tai[make_pair(a, b)]) continue;
        canh_ton_tai[make_pair(a, b)] = true;
    }

    for (int i = 1; i <= so_nut_A; ++i) {
        memset(danh_dau, 0, sizeof(danh_dau));
        if (tim_ket_noi(i)) ket_qua++;
    }

    cout << ket_qua;
    return 0;
}

Bài toán phủ đỉnh cực tiểu (Bài P7368)


#include <bits/stdc++.h>
using namespace std;

long long n, k;
long long danh_dau[501], ket_noi[MAX_NUT], ket_qua;
map<pair<long long, long long>, bool> canh_ton_tai;

bool tim_ket_noi(long long nut) {
    for (int i = 1; i <= n; ++i) {
        if (danh_dau[i] || !canh_ton_tai[make_pair(nut, i)]) continue;
        danh_dau[i] = 1;
        if (!ket_noi[i] || tim_ket_noi(ket_noi[i])) {
            ket_noi[i] = nut;
            return true;
        }
    }
    return false;
}

int main() {
    cin >> n >> k;
    for (int i = 0; i < k; ++i) {
        long long a, b;
        cin >> a >> b;
        canh_ton_tai[make_pair(a, b)] = true;
    }

    for (int i = 1; i <= n; ++i) {
        memset(danh_dau, 0, sizeof(danh_dau));
        if (tim_ket_noi(i)) ket_qua++;
    }

    cout << ket_qua;
    return 0;
}

Thuật toán KM cho cặp ghép trọng số cực đại (Bài P1559)


#include <bits/stdc++.h>
using namespace std;

#define MAX_N 105
#define INF 1e9+7

long long n;
long long do_uu_tien[MAX_N][MAX_N], do_uu_tien_nho[MAX_N][MAX_N];
long long danh_dau_x[MAX_N], danh_dau_y[MAX_N], ket_noi[MAX_N], ket_qua;
long long gan_x[MAX_N], gan_y[MAX_N], khoang_cach[MAX_N];

bool tim_ket_noi(long long u) {
    danh_dau_x[u] = 1;
    for(int v = 1; v <= n; ++v) {
        if(danh_dau_y[v]) continue;
        long long t = gan_x[u] + gan_y[v] - do_uu_tien[u][v];
        if(t == 0) {
            danh_dau_y[v] = 1;
            if(!ket_noi[v] || tim_ket_noi(ket_noi[v])) {
                ket_noi[v] = u;
                return true;
            }
        } else {
            khoang_cach[v] = min(khoang_cach[v], t);
        }
    }
    return false;
}

void giai_quyet() {
    memset(ket_noi, 0, sizeof(ket_noi));
    memset(gan_x, 0, sizeof(gan_x));
    memset(gan_y, 0, sizeof(gan_y));

    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            gan_x[i] = max(gan_x[i], do_uu_tien[i][j]);

    for(int i = 1; i <= n; ++i) {
        while(true) {
            memset(danh_dau_x, 0, sizeof(danh_dau_x));
            memset(danh_dau_y, 0, sizeof(danh_dau_y));
            fill(khoang_cach, khoang_cach + MAX_N, INF);
            if(tim_ket_noi(i)) break;
            
            long long minn = INF;
            for(int j = 1; j <= n; ++j)
                if(!danh_dau_y[j]) minn = min(minn, khoang_cach[j]);
                
            for(int j = 1; j <= n; ++j) {
                if(danh_dau_x[j]) gan_x[j] -= minn;
                if(danh_dau_y[j]) gan_y[j] += minn;
            }
        }
    }

    long long tong = 0;
    for(int i = 1; i <= n; ++i) {
        tong += gan_x[i];
        if(ket_noi[i]) tong += gan_y[i];
    }
    cout << abs(tong);
}

int main() {
    cin >> n;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            cin >> do_uu_tien[i][j];
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            cin >> do_uu_tien_nho[i][j];
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            do_uu_tien[i][j] = do_uu_tien[i][j] * do_uu_tien_nho[j][i];
    
    giai_quyet();
    return 0;
}

Thẻ: thuat-toan-km do-thi-hai-phia tim-canh-cuc-dai luan-ly-hop-khong-gian

Đăng vào ngày 28 tháng 6 lúc 23:05