Cod sursa(job #2958496)

Utilizator alex_bb8Banilean Alexandru-Ioan alex_bb8 Data 26 decembrie 2022 19:25:58
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.93 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 20002;

struct edge{
    int node, flow, capacity;  
};

int n, m, e;
vector<edge> G[NMAX];

void add_edge(int x, int y){
    
    G[x].push_back({y, 0, 1});
    G[y].push_back({x, 0, 0});
}

void read(){

    f >> n >> m >> e;

    for(int i = 1; i <= e; ++i){
        int x, y;
        
        f >> x >> y;
        
        add_edge(x , n + y);
    }

}

bool BFS(int s, int t, vector<int>& parent){
    
    fill(parent.begin(), parent.end(), -1);
    
    queue<int> Q;

    Q.push(s);
    
    parent[s] = -2;

    while(!Q.empty()){
        
        int node = Q.front();
        
        Q.pop();

        for(auto& link : G[node]){
            if(parent[link.node] == -1 && link.capacity - link.flow > 0){
                parent[link.node] = node;

                if(link.node == t)
                    return true;

                Q.push(link.node);
            }
        }
    }

    return false;
}

void solve(){

    int max_flow = 0, s = 0, t = n + m + 1;
    vector<int> parent(n + m + 3, -1);

    for(int i = 1; i <= n; ++i)
        add_edge(s, i);
    
    for(int i = 1; i <= m; ++i)
        add_edge(n + i, t);
    
    while(BFS(s, t, parent)){
        
        int path_flow = INT_MAX;
        
        // find the max flow through the path
        for(int node = t; node != s; node = parent[node]){
            int aux = parent[node], index_node;
            
            for(index_node = 0; index_node < G[aux].size(); ++index_node)
                if(G[aux][index_node].node == node)
                    break;
            
            path_flow = min(path_flow, G[aux][index_node].capacity - G[aux][index_node].flow);
        }

        
        // update
        for(int node = t; node != s; node = parent[node]){
            int aux = parent[node], index_aux, index_node;
            
            for(index_aux = 0; index_aux < G[node].size(); ++index_aux)
                if(G[node][index_aux].node == aux)
                    break;
            
            for(index_node = 0; index_node < G[aux].size(); ++index_node)
                if(G[aux][index_node].node == node)
                    break;
            
            if(path_flow > 0){
                
                G[aux][index_node].flow += path_flow;
                G[node][index_aux].flow -= path_flow;
            }
        }
        
        max_flow += path_flow;
    }
    
    g << max_flow << '\n';
    
    for(int node = 1; node <= n; ++node){
        for(auto& link : G[node])
            if(link.flow == 1)
                g << node << ' ' << link.node - n << '\n'; 
    }
    
}

int main(){
    
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    read();
    
    solve();

    f.close();
    g.close();

    return 0;
}