Cod sursa(job #2966751)

Utilizator SurtexXGheorghe Robert-Mihai SurtexX Data 18 ianuarie 2023 12:39:18
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <tuple>
#include <climits>
using namespace std;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

int n, m, e, N;
vector<int> viz;
vector<pair<int, int>>root;
vector<vector<tuple<int, int,int>>> lista;

int bfs() {
    queue<int> q;
    q.push(0);
    for (int i = 0; i <= N; i++) {
        root[i] = { -1, -1 };
        viz[i] = 0;
    }
    viz[0]++;

    while (q.size() != 0) {
        int node = q.front();
        if (node == N)
            return 1;
        int poz = 0;
        for (auto x:lista[node]) {
            int neighbour = get<0>(x);
            int capacity = get<1>(x);
            if (capacity > 0 && viz[neighbour] == 0) {
                viz[neighbour]++;
                root[neighbour] = { node, poz };
                q.push(neighbour);

            }
            poz++;
        }
        q.pop();
    }
    return 0;
}

int Edmonds_Karp() {
    int max_flux = 0;
    while (bfs()) {
		for (auto x : lista[N]) {
            int node = get<0>(x);
			if (get<1>(lista[node][get<2>(x)]) > 0 && viz[node]) {
                int minim = INT_MAX;
                root[N] = { node, get<2>(x)};
                int drum = N;
                while (root[drum].first != -1) {
                    minim = min(minim, get<1>(lista[root[drum].first][root[drum].second]));
                    drum = root[drum].first;
                }


                max_flux += minim;
                drum = N;
                while (root[drum].first != -1) {
                    get<1>(lista[root[drum].first][root[drum].second]) -= minim;
                    get<1>(lista[drum][get<2>(lista[root[drum].first][root[drum].second])]) += minim;
                    drum = root[drum].first;
                }

            }
        }
    }
    return max_flux;

}


int main()
{
    f >> n >> m >> e;
	lista = vector<vector<tuple<int, int, int>>>(n + m + 2);
	root = vector<pair<int,int>>(n + m + 2);
	viz = vector<int>(n + m + 2);
    N = n + m + 1;
    for (int i = 0; i < e; i++) {
        int x, y;
        f >> x >> y;
        lista[x].push_back({y + n ,1, lista[y + n].size() });
        lista[y + n].push_back({ x, 0, lista[x].size() - 1 });
    }
    for (int i = 1; i <= n; i++) {
        lista[0].push_back({ i, 1, lista[i].size() });
        lista[i].push_back({ 0, 0, lista[0].size() - 1 });
    }
    for (int i = 1; i <= m; i++) {
        lista[i + n].push_back({ n + m + 1, 1, lista[N].size() });
        lista[n + m + 1].push_back({ i + n, 0, lista[i + n].size() - 1 });
    }
    g << Edmonds_Karp() << "\n";

    for (int i = 1; i <= n; i++)
        for (int j = 0; j < lista[i].size(); j++) {
            if (get<1>(lista[i][j]) != 1 && get<0>(lista[i][j])!= 0)
                g << i << " " << get<0>(lista[i][j]) - n << "\n";
        }
}