Cod sursa(job #1835735)

Utilizator mucenic_b101Bogdan Mucenic mucenic_b101 Data 27 decembrie 2016 13:14:16
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.03 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#define MAXN 10000
#define MAXNODES 20005
using namespace std;

struct Edge{
    int u, v;

    int flow, cap;

    Edge(int a, int b) {
        u = a;
        v = b;
        cap = 1;
        flow = 0;
    }

    int getNeighbour(int node) {
        return u + v - node;
    }

    int getCapacity(int node) {
        return node == u ? cap : 0;
    }

    int getFlow(int node) {
        return node == u ? flow : -flow;
    }

    int getResidualCapacity(int node) {
        return getCapacity(node) - getFlow(node);
    }

    void addFlow(int node, int val) {
        if (node == u)
            flow += val;
        else
            flow -= val;
    }

};

vector <Edge*> G[MAXNODES];
Edge* pre[MAXNODES];

Edge* NIL = new Edge(-1, -1);

int cuplat[MAXNODES];

int n, m, e;
int S, D;

int pereche[5];

typedef queue <int> Queue;
Queue Q;

inline bool BFS() {

    for (int i = S ; i <= D ; ++i)
        pre[i] = NIL;

    while (!Q.empty())
        Q.pop();

    Q.push(S);

    while (!Q.empty()) {
        int node = Q.front();
        Q.pop();

        if (node == D)
            return true;

        for (int i = 0 ; i < G[node].size() ; ++i) {
            int vecin = G[node][i]->getNeighbour(node);
            if (vecin != S && pre[vecin] == NIL && G[node][i]->getResidualCapacity(node)) {
                pre[vecin] = G[node][i];
                Q.push(vecin);
            }
        }

    }

    return false;
}

int main () {
    ifstream cin("cuplaj.in");
    ofstream cout("cuplaj.out");

    cin >> n >> m >> e;
    S = 0;
    D = n + m + 1;

    for (int i = 1 ; i <= n ; ++i) {
        Edge* muchie = new Edge(S, i);

        G[S].push_back(muchie);
        G[i].push_back(muchie);
    }

    for (int i = n + 1 ; i <= n + m ; ++i) {
        Edge* muchie = new Edge(i, D);

        G[i].push_back(muchie);
        G[D].push_back(muchie);
    }

    for (int i = 0 ; i < e ; ++i) {
        int a, b;
        cin >> a >> b;

        Edge* muchie = new Edge(a, n + b);

        G[a].push_back(muchie);
        G[n + b].push_back(muchie);
    }

    int sol = 0;
    memset(cuplat, -1, sizeof(cuplat));
    while (BFS()) {
        //fluxul e sigur 1
        ++sol;

        int node = D;
        pereche[0] = 0;

        while (node != S) {
            if (node != D)
                pereche[++pereche[0]] = node;

            if (pereche[0] == 2) {
                cuplat[pereche[1]] = pereche[2];
                cuplat[pereche[2]] = pereche[1];
                pereche[0] = 0;
            }

            pre[node]->addFlow(pre[node]->getNeighbour(node), 1);
            node = pre[node]->getNeighbour(node);
        }

    }

    cout << sol << "\n";

    for (int i = 1 ; sol ; ++i) {
        if (cuplat[i] != -1) {
            cout << i << " " << cuplat[i] - n << "\n";
            --sol;
        }
    }

    return 0;
}