Cod sursa(job #2886091)

Utilizator verde.cristian2005Verde Flaviu-Cristian verde.cristian2005 Data 6 aprilie 2022 22:49:42
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int dim=1<<17;
char next_ch()
{
    static int bp=dim;
    static char buff[dim];
    if(bp==dim)
    {
        fread(buff,1,dim,stdin);
        bp=0;
    }
    return buff[bp++];
}
void get(int &a)
{
    a=0;
    char ch;
    do
    {
        ch=next_ch();
    }
    while(ch<'0'||'9'<ch);
    do
    {
        a=a*10+ch-'0';
        ch=next_ch();
    }
    while('0'<=ch&&ch<='9');
}
using T=int;
struct Dinic
{
    struct Edge
    {
        int a,b,ult;
        T flow,cap;
    };

    int n;
    Edge *es = new Edge[120001];
    int last[120001],dist[120001],coada[120001],cnt;

    Dinic(int n) : n(n),cnt(0) {}

    void AddEdge(int a,int b,T c)
    {
        es[++cnt]= {a,b,last[a],0,c};
        last[a]=cnt;
        es[++cnt]= {b,a,last[b],0,0};
        last[b]=cnt;
    }
    bool bfs(int s,int t)
    {
        int cnt1=0;
        for(int i=1; i<=n; i++)
            dist[i]=-1;
        dist[s]=0;
        coada[++cnt1]=s;
        for(int i=1; i<=cnt1; i++)
        {
            int it=coada[i];
            for(int x=last[it]; x; x=es[x].ult)
            {
                if(dist[es[x].b]==-1&&es[x].cap>es[x].flow)
                {
                    dist[es[x].b]=dist[it]+1;
                    coada[++cnt1]=es[x].b;
                }
            }
        }
        //for(int i=1; i<last.size(); i++)
        //out<<dist[i]<<" ";
        //out<<'\n';
        return (dist[t]!=-1);
    }
    T dfs(int s,int t,T pas)
    {
        T tot=0;
        if(s==t||pas==0)
            return pas;
        for(int x=last[s]; x; x=es[x].ult)
        {
            if(dist[es[x].b]==dist[s]+1&&es[x].cap>es[x].flow)
            {
                T cat=dfs(es[x].b,t,min(pas,es[x].cap-es[x].flow));
                if(cat)
                {
                    es[x].flow+=cat;
                    es[x^1].flow-=cat;
                    tot+=cat;
                    pas-=cat;
                }
            }
            if(!pas)
                break;
        }
        return tot;
    }
    T Compute(int s,int t)
    {
        T rez=0;
        while(bfs(s,t))
            rez+=dfs(s,t,numeric_limits<T>::max());
        return rez;
    }
};
int main()
{
    freopen("cuplaj.in","r",stdin);
    freopen("cuplaj.out","w",stdout);
    int n,m,i,a,b,p;
    get(n);
    get(p);
    get(m);
    Dinic d(n+p+2);
    for(i=2; i<=n+1; i++)
        d.AddEdge(1,i,1);
    for(i=1; i<=m; i++)
    {
        get(a);
        get(b);
        d.AddEdge(1+a,n+1+b,1);
    }
    for(i=1; i<=p; i++)
        d.AddEdge(n+1+i,n+p+2,1);
    cout<<d.Compute(1,n+p+2)<<'\n';
    for(int it=1; it<=d.cnt; it++)
        if(d.es[it].cap==d.es[it].flow&&d.es[it].a>=2&&d.es[it].a<=n+1&&d.es[it].b>=n+2&&d.es[it].b<=n+p+1)
            cout<<d.es[it].a-1<<" "<<d.es[it].b-n-1<<'\n';
    return 0;
}