Cod sursa(job #2962127)

Utilizator vlanderovlad rosu vlandero Data 7 ianuarie 2023 19:55:19
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("./maxflow.in");
ofstream fout("./maxflow.out");

struct Edge {
    int next;
    int capacity;
};

vector<unordered_map<int, int>> edges;
vector<vector<Edge>> adjList;
vector<int> tt;
vector<int> viz;
int n, m, l, r;

bool bfs()
{
    for(int i = 0; i <= n; ++i)
    {
        tt[i] = 0;
        viz[i] = 0;
    }
    viz[0] = 1;
    queue<int> q;
    q.push(0);
    while(!q.empty())
    {
        int crt = q.front();
        q.pop();
        for(Edge node : adjList[crt])
        {
            if(viz[node.next] == 0 && adjList[crt][edges[crt][node.next]].capacity > 0)
            {
                q.push(node.next);
                viz[node.next] = 1;
                tt[node.next] = crt;
                if(node.next == n)
                    return true;
            }
        }
    }
    return false;
}

int getFlow()
{
    int flow = INT_MAX;
    int i = n;
    while(i != 0)
    {
        flow = min(flow, adjList[tt[i]][edges[tt[i]][i]].capacity);
        i = tt[i];
    }
    return flow;
}

void updateResidual(int flow)
{
    int i = n;
    while(i != 0)
    {
        adjList[i][edges[i][tt[i]]].capacity += flow;
        adjList[tt[i]][edges[tt[i]][i]].capacity -= flow;
        i = tt[i];
    }
}

void getMatchingEdges() {
    for (int i = 1; i <= l; ++i) {
        for (Edge e : adjList[i]) {
            if (e.capacity == 0 && e.next != 0 && e.next != n) {
                fout <<  i << " " << e.next - l  << '\n';
            }
        }
    }
}


int main()
{
    fin>>l>>r>>m;
    n = l + r + 1;
    tt.resize(n + 1);
    viz.resize(n + 1);
    edges.resize(n + 1);
    adjList.resize(n + 1);
    int x, y;
    int res = 0;
    for(int i = 0; i < m; ++i)
    {
        fin>>x>>y;
        adjList[x].push_back({y + l, 1});
        adjList[y + l].push_back({x, 0});
        edges[x][y + l] = adjList[x].size() - 1;
        edges[y + l][x] = adjList[y + l].size() - 1;
    }
    for(int i = 1; i <= l; ++i){
        adjList[0].push_back({i, 1});
        adjList[i].push_back({0, 0});
        edges[0][i] = adjList[0].size() - 1;
        edges[i][0] = adjList[i].size() - 1;
    }
    for(int i = l + 1; i <= l + r; ++i){
        adjList[i].push_back({n, 1});
        adjList[n].push_back({i, 0});
        edges[i][n] = adjList[i].size() - 1;
        edges[n][i] = adjList[n].size() - 1;
    }

    while(bfs())
    {
        int flow = getFlow();
        res += flow;
        updateResidual(flow);
    }

    fout<<res<<'\n';
    getMatchingEdges();

    return 0;
}