Cod sursa(job #2698451)

Utilizator theo2003Theodor Negrescu theo2003 Data 22 ianuarie 2021 10:14:33
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
#include <vector>
using namespace std;
int l, r, e;
struct edge{
    int to;
    int c;
    int rev;
    bool main;
};
vector<edge> g[20005];
int bfs[20005], pv[20005], v[20005], vnr = 1, s, i, flow = 0;
edge *pve[20005];
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
int main(){
    //ios_base::sync_with_stdio(0);
    //cin.tie(0);
    //cout.tie(0);
    cin>>l>>r>>e;
    for(int x = 1;x<=l;x++){
        g[0].push_back({x, 1, 0});
        g[x].push_back({0, 0, x-1});
    }
    for(int x = 1;x<=r;x++){
        g[l+x].push_back({l+r+1, 1, x-1});
        g[l+r+1].push_back({l+x, 0, 0});
    }
    for(int x = 0, u, v;x<e;x++){
        cin>>u>>v;
        g[u].push_back({l + v, 1, g[l+v].size(), true});
        g[l+v].push_back({u, 0, g[u].size()-1});
    }
    while(true){
        bfs[0] = 0;
        s = 1;
        v[0] = ++vnr;
        i = 0;
        bool bbb = false;
        while(i < s){
            for(auto &a : g[bfs[i]]){
                if(a.to == (l+r+1)){
                    if(a.c == 0)
                        goto no;
                    for(int x = bfs[i];x != 0;x = pv[x]){
                        if(g[pve[x]->to][pve[x]->rev].c <= 0)
                            goto no;
                    }
                    a.c--;
                    g[l+r+1][a.rev].c++;
                    for(int x = bfs[i];x != 0;x = pv[x]){
                        pve[x]->c++;
                        g[pv[x]][pve[x]->rev].c--;
                    }
                    flow++;
                    bbb = true;
                    continue;
                }
                no:if((v[a.to] != vnr) && (a.c > 0)){
                    bfs[s++] = a.to;
                    pv[a.to] = bfs[i];
                    v[a.to] = vnr;
                    pve[a.to] = &g[a.to][a.rev];
                }
            }
            i++;
        }
        if(!bbb)
            break;
    }
    cout<<flow<<'\n';
    for(int x = 1;x<=l;x++){
        for(auto y : g[x]){
            if(y.main && !y.c){
                cout<<x<<' '<<y.to - l<<'\n';
            }
        }
    }
    return 0;
}