Cod sursa(job #2606880)

Utilizator cyg_vladioanBirsan Vlad cyg_vladioan Data 28 aprilie 2020 19:57:33
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>
using namespace std;
const int NMAX = 10000;
const int MMAX = 10000;
const int EMAX = 2* (100000 + NMAX + MMAX);
const int INF = INT_MAX;
struct muchii
{
    int x , y , cf;
    muchii(int tx = 0 , int ty = 0 , int tcf = 1)
    {
        x = tx;
        y = ty;
        cf = tcf;
    }
};
muchii v[EMAX + 5];
struct graf
{
    int nod , poz;
    graf(int tnod = 0 , int tpoz = 0)
    {
        nod = tnod;
        poz = tpoz;
    }
};
vector <graf> G[NMAX + MMAX + 5];
int viz[NMAX + MMAX + 5] , poz[EMAX + 5] , s , t;
int bfs()
{
    int i , j , x , y , muchie;
    for(i = 0 ; i <= t ; i ++)
        viz[i] = -1;
    queue <int> q;
    q.push(s);
    viz[s] = -2;
    while(!q.empty())
    {
        x = q.front();
        q.pop();
        if(x == t)
            continue;
        for(j = 0 ; j < G[x].size() ; j ++)
        {
            y = G[x][j].nod;
            muchie = G[x][j].poz;
            if(viz[y] == -1 && v[muchie].cf > 0)
            {
                viz[y] = muchie;
                q.push(y);
            }
        }
    }
    if(viz[t] == -1)
        return 0;
    return 1;
}
void update_flow()
{
    int nod , flow;
    flow = INF;
    for(nod = t ; viz[nod] != -2 ; nod = v[viz[nod]].x)
        flow = min(flow , v[viz[nod]].cf);
    for(nod = t ; viz[nod] != -2 ; nod = v[viz[nod]].x)
    {
        v[viz[nod]].cf = v[viz[nod]].cf - flow;
        v[viz[nod] ^ 1].cf = v[viz[nod] ^ 1].cf + flow;
    }
}
int max_flow()
{
    int j , nod , cf , muchie , flow;
    while(bfs())
        for(int j = 0 ; j < G[t].size() ; j ++)
        {
            nod = G[t][j].nod;
            muchie = G[t][j].poz;
            cf = v[muchie ^ 1].cf;
            if(cf == 0 || viz[nod] == -1)
                continue;
            viz[t] = (muchie ^ 1);
            update_flow();
        }
    flow = 0;
    for(j = 0 ; j < G[t].size() ; j ++)
    {
        muchie = (G[t][j].poz ^ 1);
        if(v[muchie].cf == 0)
            flow ++;
    }
    return flow;
}
int main()
{
    freopen("cuplaj.in" , "r" , stdin);
    freopen("cuplaj.out" , "w" , stdout);
    int n , m , e , x , y , mch , i;
    scanf("%d%d%d" , &n , &m , &e);
    mch = -1;
    for(i = 1 ; i <= e ; i ++)
    {
        scanf("%d%d" , &x , &y);
        v[++ mch] = muchii(x , y + n);
        G[x].push_back(graf(y + n , mch));
        v[++ mch] = muchii(y + n , x , 0);
        G[y + n].push_back(graf(x , mch));
        if(viz[x] == 0)
        {
            v[++ mch] = muchii(0 , x);
            G[0].push_back(graf(x , mch));
            v[++ mch] = muchii(x , 0 , 0);
            G[x].push_back(graf(0 , mch));
        }
        if(viz[y + n] == 0)
        {
            v[++ mch] = muchii(y + n , n + m + 1);
            G[y + n].push_back(graf(n + m + 1 , mch));
            v[++ mch] = muchii(n + m + 1 , y + n , 0);
            G[n + m + 1].push_back(graf(y + n , mch));
        }
        viz[x] = viz[y + n] = 1;
    }
    s = 0;
    t = n + m + 1;
    printf("%d\n" , max_flow());
    for(i = 0 ; i <= mch ; i ++)
        if(v[i].cf == 0 && v[i].x >= 1 && v[i].x <= n && v[i].y >= n + 1 && v[i].y <= n + m)
            printf("%d %d\n" , v[i].x , v[i].y - n);
    return 0;
}