Cod sursa(job #2884932)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 5 aprilie 2022 11:10:24
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <bits/stdc++.h>

using namespace std;
typedef int ll;
const ll NMAX=2e4+5,MMAX=1e5+5;
struct edge{
    int u=0, v=0;
    bool active=0;
}edges[MMAX*2+NMAX*2];
vector<ll> edg[NMAX];
ll layer[NMAX],ptr[NMAX];
ll s,t,n,n2,m;
bool dfs(ll u){
    if(u==t) return 1;
    for(ll& i=ptr[u];i<edg[u].size();i++){
        #define it edges[edg[u][i]]
        if(layer[it.v]==layer[it.u]+1 && it.active){
            ll new_flow=dfs(it.v);

            if(new_flow){
                edges[edg[u][i]].active^=1;
                edges[edg[u][i]^1].active^=1;
                return 1;
            }
        }
        #undef it
    }
    return 0;
}
int main()
{
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");
    fin>>n>>n2>>m;
    for(ll i=0;i<m;i++){
        ll u,v;
        fin>>u>>v;
        v+=n;
        edges[i*2]={u,v,1};
        edges[i*2+1]={v,u,0};
        edg[u].push_back(i*2),edg[v].push_back(i*2+1);
    }
    s=0,t=n+n2+1;
    for(ll i=1;i<=n;i++){
        ll id=(m+i-1)*2;
        edges[id]={s,i,1};
        edges[id|1]={i,s,0};
        edg[s].push_back(id),edg[i].push_back(id|1);
    }
    for(ll i=n+1;i<=n+n2;i++){
        ll id=(m+i-1)*2;
        edges[id]={i,t,1};
        edges[id|1]={t,i,0};
        edg[i].push_back(id),edg[t].push_back(id|1);
    }
    ll ans=0;
    for(;;){
        for(ll i=0;i<=n+n2+1;i++)
            layer[i]=-1,ptr[i]=0;
        layer[s]=0;
        queue<ll> q;
        q.push(s);
        while(!q.empty()){
            for(auto it : edg[q.front()]){
                if(edges[it].active && layer[edges[it].v]==-1){
                    layer[edges[it].v]=layer[q.front()]+1,q.push(edges[it].v);
                    if(edges[it].v==t) break;
                }
            }
            q.pop();
        }
        if(layer[t]==-1) break;
        while(dfs(s)) ans++;
    }
    fout<<ans<<'\n';
    for(int i=0;i<2*m;i+=2)
        if(!edges[i].active)
             fout<<edges[i].u<<' '<<edges[i].v-n<<'\n';
    return 0;
}