Cod sursa(job #2711881)

Utilizator OvidRata Ovidiu Ovid Data 24 februarie 2021 20:19:40
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include<bits/stdc++.h>
using namespace std;
#define INIT  ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
//#define int ll

int t, n, m,E, k, a[300010], q, l, r;

vector<pii> g[40010];
int c[200101][3];
int f[200010][3];


bool v[40010];
pii p[40010];
int fat[40010];

int dijkstra(int s, int t){

for(int i=1; i<=(n+m+2); i++){
    v[i]=false;
}

multiset<pii> ms;
ms.insert({1e9, s});
fat[s]=1e9;

while(!ms.empty()){
    auto it=ms.end(); it--;
    int nod=it->sc;
    ms.erase(it);
    v[nod]=true;
    if(nod==t){break;}

    for(pii pr:g[nod]){
        int u=pr.ft, e=pr.sc;
        if(v[u]){continue;}
        auto it=ms.find({fat[u], u});
        //cout<<e<<" "<<flush;
        if(it==ms.end()){
            fat[u]=min(fat[nod], c[abs(e)][1+(e/abs(e)) ] -f[abs(e)][1+(e/abs(e)) ] );
            ms.insert({fat[u], u });
            p[u]={nod, e};
        }
        else{
            if( min(fat[nod], c[abs(e)][1+(e/abs(e)) ] -f[abs(e)][1+(e/abs(e)) ])>fat[u]  ){
                fat[u]=min(fat[nod], c[abs(e)][1+(e/abs(e)) ] -f[abs(e)][1+(e/abs(e)) ] );
                ms.erase(it);
                ms.insert({fat[u], u});
                p[u]={nod, e};
            }
        }
        //cout<<fat[u]<<" "<<u<<"x\n"<<flush;
    }


}

if(fat[t]==0){return 0;}
int cr=t;

while(cr!=0){
        int e=p[cr].sc;
        if(e==0){break;}
    f[abs(e)][1+(e/abs(e)) ]+=fat[t];
    f[abs(e)][1-(e/abs(e)) ]-=fat[t];
    cr=p[cr].ft;
}

int res=fat[t];
fat[t]=0;
return res;
}

pii pr[100010];

int32_t main(){
INIT

freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);

cin>>n>>m>>E;


for(int i=1; i<=E; i++){
    int u, v;
    cin>>u>>v;
    g[u].pb({v+n, i} );
    g[v+n].pb({u, -i} );
    c[i][2]=1;
    pr[i]={u, v};
}

int cnt=E;
for(int i=1; i<=n; i++){
    cnt++;
    g[n+m+1].pb({i, cnt} );
    g[i].pb({n+m+1, -cnt});
    c[cnt][2]=1;
}

for(int i=1; i<=m; i++){
    cnt++;
    g[n+m+2].pb({i+n, -cnt} );
    g[i+n ].pb({n+m+2, cnt});
    c[cnt][2]=1;
}


int res=0;

while(true){
    int x=dijkstra(n+m+1, n+m+2);
    if(x==0){break;}
    //cout<<x<<flush<<"\n";
    res+=x;
}



cout<<res<<"\n";

for(int i=1; i<=E; i++){
    if(f[i ][2]==1){
        cout<<pr[i].ft<<" "<<pr[i].sc<<"\n";
    }
}

return 0;
}