Cod sursa(job #3329899)

Utilizator ioanyaioana cocut ioanya Data 16 decembrie 2025 12:54:57
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.4 kb
// #include <bits/stdc++.h>
// using namespace std;
//
// const int NMAX = 1e3;
// int capacitate[NMAX + 1][NMAX + 1], flux[NMAX + 1][NMAX + 1];
// int vis[NMAX + 1], p[NMAX + 1];
// vector<int> G[NMAX + 1];
// int n, m;
//
// int bfs(int s, int d) {
//     for(int i = 1; i <= n; i++) {
//         vis[i] = 0;
//         p[i] = 0;
//     }
//     queue<int> q;
//     q.push(s);
//     vis[s] = 1;
//     while(!q.empty()) {
//         int nod = q.front();
//         q.pop();
//         for(auto vecin : G[nod]) {
//             if(!vis[vecin] && capacitate[nod][vecin] - flux[nod][vecin] > 0) {
//                 vis[vecin] = 1;
//                 q.push(vecin);
//                 p[vecin] = nod;
//             }
//         }
//     }
//     if(vis[d] == 0) {
//         return 0;
//     }
//     vector<int> path;
//     while(d != 0) {
//         path.push_back(d);
//         d = p[d];
//     }
//     reverse(path.begin(), path.end());
//     int flow = 1e9;
//     for(int i = 0; i < path.size() - 1; i++) {
//         int x = path[i];
//         int y = path[i + 1];
//         flow = min(flow, capacitate[x][y] - flux[x][y]);
//     }
//     for(int i = 0; i < path.size() - 1; i++) {
//         int x = path[i];
//         int y = path[i + 1];
//         flux[x][y] += flow;
//         flux[y][x] -= flow;
//     }
//     return flow;
// }
//
// int main() {
//     ifstream cin("maxflow.in");
//     ofstream cout("maxflow.out");
//     cin >> n >> m;
//     for(int i = 1; i <= m; i++) {
//         int x, y, c;
//         cin >> x >> y >> c;
//         capacitate[x][y] = c;
//         G[x].push_back(y);
//         G[y].push_back(x);
//     }
//     int maxflow = 0;
//     while(true) {
//         int flow = bfs(1, n);
//         if(flow == 0) {
//             break;
//         }
//         maxflow += flow;
//     }
//     cout << maxflow;
// }

#include <bits/stdc++.h>

#define NMAX 10000

int flow[NMAX + 1][NMAX + 1];
int c[NMAX + 1][NMAX + 1];
int visited[NMAX + 1], p[NMAX + 1];

std::vector<int> G[NMAX + 1];

int BFS(int s, int d, int n_flow) {
    std::queue<int> q;
    for (int i = 1; i <= n_flow; ++i) {
        visited[i] = 0;
        p[i] = 0;
    }

    q.push(s);
    visited[s] = 1;
    while (!q.empty()) {
        const int x = q.front();
        q.pop();

        for (auto y : G[x]) {
            if (!visited[y] && c[x][y] - flow[x][y] > 0) {
                visited[y] = 1;
                q.push(y);
                p[y] = x;
            }
        }
    }

    if (visited[d] == 0) {
        return 0;
    }

    std::vector<int> path;
    int x = d;
    while (x != 0) {
        path.push_back(x);
        x = p[x];
    }

    std::ranges::reverse(path);

    int mn = 1e9;
    for (int i = 0; i + 1 < path.size(); ++i) {
        int x = path[i];
        int y = path[i + 1];
        mn = std::min(mn, c[x][y] - flow[x][y]);
    }
    for (int i = 0; i + 1 < path.size(); ++i) {
        int x = path[i];
        int y = path[i + 1];
        flow[x][y] += mn;
        flow[y][x] -= mn;
    }

    return mn;
}

int main() {
    int n, m, e;
    std::ifstream cin("cuplaj.in");
    std::ofstream cout("cuplaj.out");

    cin >> n >> m >> e;
    int n_flow(n + m + 2), src(1), dest(n_flow);

    for (int u = 1; u <= n; ++u) {
        int u_flow = u + 1;
        c[src][u_flow] = 1;
        G[src].push_back(u_flow);
        G[u_flow].push_back(src);
    }

    for (int v = 1; v <= m; ++v) {
        int v_flow = n + 1 + v;
        c[v_flow][dest] = 1;
        G[v_flow].push_back(dest);
        G[dest].push_back(v_flow);
    }

    for (int i = 1; i <= e; ++i) {
        int u, v;
        cin >> u >> v;

        int u_flow = u + 1;
        int v_flow = n + 1 + v;

        c[u_flow][v_flow] = 1;
        G[u_flow].push_back(v_flow);
        G[v_flow].push_back(u_flow);
    }

    int sum = 0;
    while (true) {
        int f = BFS(src, dest, n_flow);
        sum += f;

        if (f == 0) {
            break;
        }
    }

    cout << sum << std::endl;
    for (int u_flow = 2; u_flow <= n + 1; ++u_flow) {
        for (int v_flow : G[u_flow]) {
            if (v_flow >= n + 2 && v_flow <= n + m + 1 && flow[u_flow][v_flow] == 1) {
                    cout << u_flow - 1 << " " << v_flow - (n + 1) << std::endl;
                }
        }
    }
    return 0;
}