Cod sursa(job #2741373)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 15 aprilie 2021 22:06:19
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <bits/stdc++.h>

using namespace std;

#ifndef LOCAL

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

#define cin in
#define cout out

#endif //LOCAL

struct Edge
{
    int u, v;
    long long cap, flow;

    Edge(int _u, int _v, int _cap)
    {
        u = _u; v = _v;
        cap = _cap;
        flow = 0;
    }
};

struct Dinic {
    const long long flow_inf = 1;
    vector<Edge> edges;
    vector<vector<int>> adj;

    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int _n, int _s, int _t)
    {
        n = _n; s = _s; t = _t;

        adj.resize(n + 7);
        level.resize(n + 7);
        ptr.resize(n + 7);
    }

    void addEdge(int u, int v, long long cap)
    {
        edges.push_back(Edge(u, v, cap));
        edges.push_back(Edge(v, u, 0));

        adj[u].push_back(m);
        adj[v].push_back(m + 1);

        m += 2;
    }

    bool bfs()
    {
        while(!q.empty())
        {
            int u = q.front();
            q.pop();

            for(int id : adj[u])
            {
                if(edges[id].cap - edges[id].flow < 1)
                    continue;
                if(level[edges[id].v] != -1)
                    continue;
                level[edges[id].v] = level[u] + 1;
                q.push(edges[id].v);
            }
        }

        return level[t] != -1;
    }

    long long dfs(int u, long long pushed)
    {
        if(pushed == 0)
            return 0;
        if(u == t)
            return pushed;

        for(int& cid = ptr[u]; cid < adj[u].size(); ++cid)
        {
            int id = adj[u][cid];
            int v = edges[id].v;

            if(level[u] + 1 != level[v] || edges[id].cap - edges[id].flow < 1)
                continue;

            long long tr = dfs(v, min(pushed, edges[id].cap - edges[id].flow));

            if(tr == 0)
                continue;

            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;

            return tr;
        }

        return 0;
    }

    long long flow()
    {
        long long f = 0;
        while(true)
        {
            fill(level.begin(), level.end(), - 1);
            level[s] = 0;
            q.push(s);
            if(!bfs())
                break;

            fill(ptr.begin(), ptr.end(), 0);

            while(long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }

        return f;
    }
};

int main()
{
    int n, m, e;
    cin >> n >> m >> e;

    //{0} + |LEFT| + |RIGHT| + {n + m + 1}
    Dinic solver(n + m + 2, 0, n + m + 1);
    
    for(int i = 0; i < e; i++)
    {
        int l, r;
        cin >> l >> r;
        solver.addEdge(l, n + r, 1);
    }

    for(int i = 1; i <= n; i++)
        solver.addEdge(0, i, 1);

    for(int i = n + 1; i <= n + m; i++)
        solver.addEdge(i, n + m + 1, 1);

    cout << solver.flow() << '\n';
    for(auto e : solver.edges)
    {
        if(e.flow == 1 && e.u != 0 && e.v != n + m + 1)
            cout << e.u << ' ' << e.v - n << '\n';
    }
}