Cod sursa(job #2962841)

Utilizator a.dulumanDuluman Andrada-Georgiana a.duluman Data 9 ianuarie 2023 17:00:19
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.05 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

int n, m, e, s, t;
vector<bool> rightpart;
vector<pair <int, int>> parinte;
vector<pair <int, int>> nodes;
vector< vector<pair <int, pair<int, int> >>> graph;

bool BFS() 
{
    vector<bool> viz(t + 1);
    queue<int> myq;

    myq.push(s);
    viz[s] = true;
    parinte[s] = { -1, -1 };

    while (!myq.empty()) 
    {
        int u = myq.front();
        myq.pop();

        if (u == t)
            continue;

        int i = 0;
        for (auto nod : graph[u]) 
        {
            int v, cap; 
            v = nod.first;
            cap = nod.second.first;
            if (!viz[v] && cap) 
            {
                parinte[v] = { u, i };
                viz[v] = true;
                myq.push(v);
            }
            i++;
        }
    }
    return viz[t];
}

long CalcMaxFlow() 
{
    long maxflow = 0;
    while (BFS()) 
    {
        for (auto nod : nodes) 
        {
            int u, v, i, j, distmin = 1;
            parinte[t] = nod;
            v = t;
            while (parinte[v].first != -1) 
            {
                u = parinte[v].first;
                i = parinte[v].second;
                distmin = min(distmin, graph[u][i].second.first);
                v = u;
            }
            v = t;
            while (parinte[v].first != -1) {
                u = parinte[v].first;
                i = parinte[v].second;
                j = graph[u][i].second.second;
                graph[u][i].second.first -= distmin;
                graph[v][j].second.first += distmin;
                v = u;
            }
            maxflow += distmin;
        }
    }
    return maxflow;
}

int main() 
{
    fin >> n >> m >> e;
    s = 0;
    t = n + m + 1;
    graph.resize(t + 1);
    rightpart.resize(m + 1);
    parinte.resize(t + 1);

    for (int i = 1; i <= n; i++)
    {
        graph[s].push_back({ i, {1, graph[i].size()} });
        graph[i].push_back({ s, {0, graph[s].size() - 1} });
        if (i == t)
            nodes.emplace_back(s, graph[s].size() - 1);
    }

    for (int i = 1; i <= e; i++) 
    {
        int u, v;
        fin >> u >> v;
        graph[u].push_back({ n + v, {1, graph[n + v].size()} });
        graph[n + v].push_back({ u, {0, graph[u].size() - 1} });
        if (n + v == t)
            nodes.emplace_back(u, graph[u].size() - 1);
        rightpart[v] = true;
    }

    for (int i = 1; i <= m; i++)
        if (rightpart[i])
        {
            graph[n + i].push_back({ t, {1, graph[t].size()} });
            graph[t].push_back({ n + i, {0, graph[n + i].size() - 1} });
            if (t == t)
                nodes.emplace_back(n + i, graph[n + i].size() - 1);
        }  

    fout << CalcMaxFlow() << '\n';
    for (int i = 1; i <= n; i++)
        for (auto nod : graph[i]) 
        {   
            int u, v;
            u = nod.first;
            v = nod.second.first;
            if (u && v == 0 && u != t)
                fout << i << " " << u - n << '\n';
        }
    return 0;
}