Cod sursa(job #2967873)

Utilizator catalin28Gheorghe Catalin catalin28 Data 20 ianuarie 2023 11:20:00
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <bits/stdc++.h>
#define INF 2147000000
using namespace std;

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

struct edge{
    int x, y, capacity, pos;
};

int n, m, a, b, c, l, r;
vector<vector<int>> adjlist, oneway;
vector<edge> edges;

// Edmonds-Karp
// O(VE^2)
int maxflow(int s, int t) {
    int flow = 0;
    vector<int> parent(n + 4);
//    vector<bool> visited(n + 2, false);
    while (true) {
        fill(parent.begin(), parent.end(), -1);
        queue<int> q;
        q.push(s);
        parent[s] = -2;
        while (!q.empty() && parent[t] == -1) { // Run BFS until the sink is visited or the queue is empty
            int u = q.front();
//            g << u << "\n";
            q.pop();
            for (int id : adjlist[u]) {
                auto v = edges[id].y;
                if (parent[v] == -1 && edges[id].capacity > 0) {

                    parent[v] = id; // edges[id]
//                    visited[v] = true;
                    q.push(v);
                }
            }
        }
        if (parent[t] == -1) break; // If the sink has not been visited, then there is no more augmenting path

        int bottleneck = INF;
        for (int v = t; v != s; v = edges[parent[v]].x) {
            bottleneck = min(bottleneck, edges[parent[v]].capacity);
        }
        if (bottleneck)
            for (int v = t; v != s; v = edges[parent[v]].x) { // Starting from the sink, go through the path to the source
                edges[parent[v]].capacity -= bottleneck; // Reduce the capacity of the edges in the augmenting path by the bottleneck capacity
                edges[parent[v] ^ 1].capacity += bottleneck; // Increase the capacity of the reverse edges by the bottleneck capacity
            }
        flow += bottleneck;
//        g << "flowL: " << flow << "\n";
    }
    g << flow << "\n";

    return flow;
}

int main() {
    f >> l >> r >> m;
    n = l + r;
    int source = n + 1, sink = n + 2;
    adjlist.resize(2*n + 4);

    for (int i = 1; i <= m; i++) {
        f >> a >> b;

        edges.push_back({a,b+l,1});
        edges.push_back({b+l,a,0});
        adjlist[a].push_back(edges.size() - 2);
        adjlist[b+l].push_back(edges.size() - 1);
    }

    for(int i = 1; i <= l; i ++){
        edges.push_back({source, i, 1});
        edges.push_back({i, source, 0});
        adjlist[source].push_back(edges.size() - 2);
        adjlist[i].push_back(edges.size() - 1);
    }

    for(int i = l + 1; i <= l + r; i ++){
        edges.push_back({i, sink, 1});
        edges.push_back({sink, i, 0});
        adjlist[i].push_back(edges.size() - 2);
        adjlist[sink].push_back(edges.size() - 1);
    }

    maxflow(source, sink);
    for(int i = 0; i < edges.size(); i += 2)
        if(edges[i].x <= n && edges[i].y <= n && edges[i].capacity == 0)
            g << edges[i].x << " " << edges[i].y - l << endl;
    return 0;
}