Cod sursa(job #1365643)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 28 februarie 2015 14:00:50
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.89 kb
/*#include <iostream>
#include <vector>
#include <queue>
#include <bitset>
#include <fstream>

using namespace std;

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

const int maxn = 10005;
const int maxm = 10005;
const int oo = 0x3f3f3f3f;

struct edge {
    int x, ind;
    edge(int _x, int _ind) {
        x = _x;
        ind = _ind;
    }
};

int n, m, e, flow[300005], cap[300005], edges;
vector <edge> g[maxn + maxm];

inline void addedge(int x, int y, int _cap, int _flow) {
    cap[edges] = _cap;
    flow[edges] = _flow;
    g[x].push_back(edge(y, edges++ ));
}

queue <int> q;
bitset <maxn + maxm> used;
int father[maxn + maxm], dadedge[maxn + maxm];

inline bool bfs(int source, int sink) {
    used.reset();
    q.push(source);
    used[source] = 1;
    while(!q.empty()) {
        int node = q.front();
        q.pop();
        if(node == sink)
            continue;
        for(vector <edge> :: iterator it = g[node].begin() ; it != g[node].end() ; ++ it)
            if(!used[it->x] && cap[it->ind] - flow[it->ind] > 0) {
                father[it->x] = node;
                dadedge[it->x] = it->ind;
                used[it->x] = 1;
                q.push(it->x);
            }
    }
    return used[sink];
}

inline int getmaxflow(int source, int sink) {
    int maxflow = 0;
    while(bfs(source, sink)) {
        for(vector <edge> :: iterator it = g[sink].begin() ; it != g[sink].end() ; ++ it) {
            if(!used[it->x] || cap[it->ind ^ 1] - flow[it->ind ^ 1] <= 0)
                continue;
            father[sink] = it->x;
            dadedge[sink ] = it->ind ^ 1;
            int bottleneck = oo;
            for(int i = sink ; i != source ; i = father[i])
                bottleneck = min(bottleneck, cap[dadedge[i]] - flow[dadedge[i]]);
            if(!bottleneck)
                continue;
            for(int i = sink ; i != source ; i = father[i]) {
                flow[dadedge[i]] += bottleneck;
                flow[dadedge[i] ^ 1] -= bottleneck;
            }
            maxflow += bottleneck;
        }
    }
    return maxflow;
}

int main() {
    fin >> n >> m >> e;
    for(int i = 1 ; i <= e ; ++ i) {
        int x, y;
        fin >> x >> y;
        addedge(x, y + n, 1, 0);
        addedge(y + n, x, 0, 0);
    }
    int source = 0, sink = n + m + 1;
    for(int i = 1 ; i <= n ; ++ i) {
        addedge(source, i, 1, 0);
        addedge(i, source, 0, 0);
    }
    for(int i = n + 1 ; i <= n + m ; ++ i) {
        addedge(i, sink, 1, 0);
        addedge(sink, i, 0, 0);
    }
    fout << getmaxflow(source, sink) << '\n';
    for(int i = 1 ; i <= n ; ++ i)
        for(vector <edge> :: iterator it = g[i].begin() ; it != g[i].end() ; ++ it)
            if(flow[it->ind] == 1)
                fout << i << ' ' << it->x - n << '\n';
}
*/

#include <iostream>
#include <vector>
#include <bitset>
#include <fstream>

using namespace std;

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

const int maxn = 10005;

int n, m, e, match_left[maxn], match_right[maxn];
vector <int> g[maxn];
bitset <maxn> used;

inline bool pairup(int node) {
    if(used[node])
        return false;
    used[node] = 1;
    for(vector <int> :: iterator it = g[node].begin() ; it != g[node].end() ; ++ it)
        if(!match_right[*it] || pairup(match_right[*it])) {
            match_right[*it] = node;
            match_left[node] = *it;
            return true;
        }
    return false;
}

int main() {
    fin >> n >> m >> e;
    for(int i = 1 ; i <= e ; ++ i) {
        int x, y;
        fin >> x >> y;
        g[x].push_back(y);
    }
    int ans = 0;
    for(bool okay = true ; okay ; ) {
        okay = false;
        used.reset();
        for(int i = 1 ; i <= n ; ++ i)
            if(!match_left[i] && pairup(i)) {
                ++ ans;
                okay = true;
            }
    }
    fout << ans << '\n';
    for(int i = 1 ; i <= n ; ++ i)
        if(match_left[i])
            fout << i << ' ' << match_left[i] << '\n';

}