Cod sursa(job #3271413)

Utilizator BogdancxTrifan Bogdan Bogdancx Data 26 ianuarie 2025 01:24:22
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.6 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

vector<vector<int>> graph, capacity;

int find_aug(int start, int end, vector<int>& parent)
{
    queue<pair<int, int>> q;
    fill(parent.begin(), parent.end(), -1);
    vector<bool> visited(end + 1, false);
    
    visited[start] = true;
    q.emplace(start, 1e9);
    
    while(!q.empty())
    {
        int node = q.front().first;
        int flow = q.front().second;
        q.pop();
        
        for(int neigh: graph[node]) {
            if(!visited[neigh] && capacity[node][neigh] > 0)
            {
                int new_flow = min(flow, capacity[node][neigh]);
                
                parent[neigh] = node;
                visited[neigh] = true;
                
                if(neigh == end)
                {
                    return new_flow;
                }
                
                q.emplace(neigh, new_flow);
            }
        }
    }
    
    return 0;
}

int max_flow(int start, int end)
{
    vector<int> parent(end + 1);
    int aug, flow = 0;
    while((aug = find_aug(start, end, parent)) != 0)
    {
        flow += aug;
        
        int t = end;
        while(t != start)
        {
            int prev = parent[t];
            capacity[prev][t] -= aug;
            capacity[t][prev] += aug;
            t = prev;
        }
    }
    
    return flow;
}

int main() {
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");
    
    int n, m, e;
    
    fin >> n >> m >> e;
    
    int super_sink = n + m + 1;
    int super_src = 0;
    
    graph.resize(n + m + 1 + 1);
    capacity.resize(n + m + 1 + 1, vector<int>(n + m + 1 + 1, 0));
    
    for(int i = 1; i <= m; i++) {
        graph[n + i].push_back(super_sink);
        graph[super_sink].push_back(n + i);
        capacity[n + i][super_sink] = 1;
    }
    
    for(int i = 1; i <= n; i++) {
        graph[0].push_back(i);
        graph[i].push_back(0);
        capacity[0][i] = 1;
    }
    
    for(int i = 1; i <= e; i++)
    {
        int a, b;
        
        fin >> a >> b;
        b += n;
        graph[a].push_back(b);
        graph[b].push_back(a);
        
        capacity[a][b] = 1;
    }
    
    fout << max_flow(super_src, super_sink) << endl;
    
    for (int i = 1; i <= n; i++) {
        for (int neigh : graph[i]) {
            if (neigh > n && neigh <= n + m && capacity[i][neigh] == 0) {
                fout << i << ' ' << neigh - n << endl;
            }
        }
    }
    
    return 0;
}