Cod sursa(job #2526332)

Utilizator Rares31100Popa Rares Rares31100 Data 18 ianuarie 2020 15:08:05
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <bits/stdc++.h>
#define PSISI pair<short int,short int>

using namespace std;

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

int n,m,e;
PSISI org[100001];
short int vf[240001],urm[240001],last[20010],nr;
map <PSISI,short int> cap,flow;
short int s,t,sum;

struct muchie
{
    int nod1,nod2;
    bool tip;
};
muchie tree[20010],start[20010],drum[20010];

void adauga(int nod,int vec)
{
    vf[++nr]=vec;
    urm[nr]=last[nod];
    last[nod]=nr;
}

bitset <20010> viz;
queue <int> c;

bool bfs()
{
    int nr=0;
    
    for(int i=s;i<=t;i++)
        viz[i]=0;
        
    viz[s]=1;
    c.push(s);
    
    while(!c.empty())
    {
        int nod=c.front();
        c.pop();
        
        if(cap[{nod,t}]-flow[{nod,t}]>0)
        {
            start[++nr]={nod,t,0};
            viz[t]=1;
        }
        else if(flow[{t,nod}]>0)
        {
            start[++nr]={nod,t,1};
            viz[t]=1;
        }
        
        for(int k=last[nod];k;k=urm[k])
            if(!viz[ vf[k] ])
            {
                int vec=vf[k];
                
                if(cap[{nod,vec}]-flow[{nod,vec}]>0)
                {
                    tree[vec]={nod,vec,0};
                    viz[vec]=1;
                    c.push(vec);
                }
                else if(flow[{vec,nod}]>0)
                {
                    tree[vec]={nod,vec,1};
                    viz[vec]=1;
                    c.push(vec);
                }
            }
    }
    
    for(int i=1;i<=nr;i++)
    {
        int poz=0;
        drum[++poz]=start[i];
        
        while(tree[ drum[poz].nod1 ].nod2)
            drum[++poz]=tree[ drum[poz].nod1 ];
        
        int minim=2;    
        
        for(int j=1;j<=poz;j++)
            if(drum[j].tip==0)
                minim=min(minim,(int)cap[{ drum[j].nod1,drum[j].nod2 }]-(int)flow[{ drum[j].nod1,drum[j].nod2 }]);
            else
                minim=min(minim,(int)flow[{ drum[j].nod2,drum[j].nod1 }]);
                
        for(int j=1;j<=poz;j++)
            if(drum[j].tip==0)
                flow[{ drum[j].nod1,drum[j].nod2 }]+=minim;
            else
                flow[{ drum[j].nod2,drum[j].nod1 }]-=minim;
                
        sum+=minim;
    }
    
    return viz[t];
}

int main()
{
    in>>n>>m>>e;
    
    s=0;
    t=n+m+1;
    
    for(int i,j,k=1;k<=e;k++)
    {
        in>>i>>j;
        org[k]={i,j};
        j+=n;
        
        cap[{i,j}]=1;
        adauga(i,j);
        adauga(j,i);
    }
    
    for(int i=1;i<=n;i++)
    {
        cap[{s,i}]=1;
        adauga(s,i);
        adauga(i,s);
    }
    
    for(int i=n+1;i<=n+m;i++)
    {
        cap[{i,t}]=1;
        adauga(i,t);
        adauga(t,i);
    }
    
    while(bfs());
    
    out<<sum<<'\n';
    
    for(int i=1;i<=e;i++)
        if(flow[{ org[i].first,org[i].second+n }])
            out<<org[i].first<<' '<<org[i].second<<'\n';
    
    return 0;
}