Cod sursa(job #2889305)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 12 aprilie 2022 16:33:11
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <bits/stdc++.h>

using namespace std;

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

const int INF = 1e9;
const int NMAX = 7000;

int N, M, E, ans, s, d;
int parent[NMAX + 1];
vector<int> adj[NMAX + 1];
vector<pair<int, int>> edges;

bitset<NMAX + 1> visited;
char capacity[NMAX + 1][NMAX + 1];
char flow[NMAX + 1][NMAX + 1];

bool bfs(int s, int d) {
    for(int i = 0; i <= N + M + 1; i++) {
        parent[i] = -1;
    }

    visited = 0;

    queue<int> q;
    q.push(s);
    visited[s] = 1;

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

        if(node == d) {
            return 1;
        }

        for(auto it: adj[node]) {
            if(flow[node][it] == capacity[node][it]) {
                continue;
            }

            if(!visited[it]) {
                visited[it] = 1;
                q.push(it);
                parent[it] = node;
            }

        }
    }

    return visited[d];
}

int main() {
    fin >> N >> M >> E;

    for(int i = 1; i <= E; i++) {
        int u, v;
        fin >> u >> v;

        v += N;

        capacity[u][v] = 1;
        adj[u].push_back(v);
        adj[v].push_back(u);
        edges.push_back({u, v});
    }

    s = 0;
    d = N + M + 1;

    for(int node = 1; node <= N; node++) {
        capacity[s][node] = 1;

        adj[s].push_back(node);
        adj[node].push_back(s);
    }

    for(int node = N + 1; node <= N + M; node++) {
        capacity[node][d] = 1;

        adj[node].push_back(d);
        adj[d].push_back(node);
    }

	while(bfs(s, d)) {
		for(auto it: adj[d]) {
			parent[d] = it;
			int maxflow = INF;

			if(flow[parent[d]][d] == capacity[parent[d]][d] || !visited[parent[d]]) {
				continue;
			}

			for(int p = d; p != s; p = parent[p]) {
				maxflow = min(maxflow, capacity[parent[p]][p] - flow[parent[p]][p]);
			}

			if(maxflow == 0) {
				continue;
			}

			for(int p = d; p != s; p = parent[p]) {
				flow[p][parent[p]] -= maxflow;
				flow[parent[p]][p] += maxflow;
			}

			ans += maxflow;
		}
	}

    fout << ans << '\n';

    for(auto it: edges) {
        if(flow[it.first][it.second]) {
            fout << it.first << " " << it.second - N << '\n';
        }
    }
    return 0;
}