Cod sursa(job #2957425)

Utilizator kanyjmkSabau Eduard kanyjmk Data 22 decembrie 2022 16:18:37
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue> 
#include <climits>
#include <set>

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

int BFS(int& n, int& source, int& target, vector<vector<int>>& capacity, vector<vector<int>>& ad_list, vector<int>& parent)
{
    vector<bool> visited(n+1, false);
    queue<pair<int, int>> bfs_q;
    bfs_q.push({source, INT_MAX});
    visited[source] = true;
    int min_flow;

    while(!bfs_q.empty())
    {
        int curr_v = bfs_q.front().first;
        int curr_flow = bfs_q.front().second;
        bfs_q.pop();
        
        for(auto next : ad_list[curr_v])
            if(!visited[next] && capacity[curr_v][next] > 0)
            {
                visited[next] = true;               
                min_flow = min(curr_flow, capacity[curr_v][next]);
                parent[next] = curr_v;

                if(next == target)
                {
                    return min_flow;
                }

                bfs_q.push({next, min_flow});
            }
    }

   return 0;
}

int main()
{
    int n, m, e, flow, source, target, size;

    fin >> n >> m >> e;

    size = 2*max(n, m) + 10;

    set<int> part1, part2;
    vector<vector<int>> capacity(size, vector<int>(size));
    vector<vector<int>> ad_list(size);
    vector<int> parent(size, -1);
    
    flow = 0;
    source = 0;
    target = size-2;

    for(int i = 1; i <= e; i++)
    {
        int x, y;
        fin >> x >> y;

        capacity[x][y+size/2] = 1;
        ad_list[x].push_back(y+size/2);
        ad_list[y+size/2].push_back(x);
        part1.insert(x);
        part2.insert(y+size/2);
    }
    for(auto it = part1.begin(); it != part1.end(); it++)
        {
            ad_list[source].push_back(*it);
            ad_list[*it].push_back(source);
            capacity[source][*it] = 1;
        }
    for(auto it = part2.begin(); it != part2.end(); it++)
        {
            ad_list[target].push_back(*it);
            ad_list[*it].push_back(target);
            capacity[*it][target] = 1;
        }
    
    while(true)
    {
        int min_flow = BFS(size, source, target, capacity, ad_list, parent);
        if(min_flow == 0)
            break;
        flow += min_flow;

        for(auto curr_v = target; curr_v != source; curr_v = parent[curr_v])
        {
            capacity[parent[curr_v]][curr_v] -= min_flow;
            capacity[curr_v][parent[curr_v]] += min_flow;
        }

    }

    fout << flow << '\n';

    for(auto it1 = part1.begin(); it1 != part1.end(); it1++)
        for(auto it2 = part2.begin(); it2 != part2.end(); it2++)
            if(capacity[*it1][*it2] == 0 && capacity[*it2][*it1] == 1)
                fout << *it1 << " " << *it2 - size / 2 << '\n';

    return 0;
}