Cod sursa(job #2958032)

Utilizator BluThund3rRadu George BluThund3r Data 24 decembrie 2022 11:41:15
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.75 kb
// /*
    
// */

// #include <bits/stdc++.h>
// using namespace std;
// ifstream in("cuplaj.in");
// ofstream out("cuplaj.out");

// class Solution {
//     int n, m, nrLeft;
//     vector<vector<int>> capacity, flow, adj;
//     vector<bool> viz;
//     vector<int> parent;

// public:
//     Solution(int _n, int _m, vector<tuple<int, int, int>> edges, int nrLeft);
//     bool bfs(int src);
//    void findMatching(int s, int t);
// };

// bool Solution::bfs(int src) {
//     fill(viz.begin(), viz.end(), false);
//     fill(parent.begin(), parent.end(), -1);
//     queue<int> q;
//     q.push(src);
//     viz[src] = true;

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

//         for(auto nextNode : adj[currNode]) 
//             if(!viz[nextNode] && capacity[currNode][nextNode] - flow[currNode][nextNode] > 0) {
//                 viz[nextNode] = true;
//                 if(nextNode != n) {
//                     q.push(nextNode);
//                     parent[nextNode] = currNode;
//                 }
//             }
//     }   

//     return viz[n];  
// } 

// void Solution::findMatching(int s, int t) {
//     int maxFlow = 0;
//     vector<pair<int, int>> matchingEdges;
//     while(bfs(s)) {
//         for(auto leaf : adj[t]) {
//             if(capacity[leaf][t] - flow[leaf][t] <= 0 || !viz[leaf])        
//                 continue;
            
//             parent[t] = leaf;
//             int minValOnPath = 110000;
//             for(int node = t; parent[node] != -1; node = parent[node])
//                 minValOnPath = min(minValOnPath, capacity[parent[node]][node] - flow[parent[node]][node]);
            
//             if(!minValOnPath)    
//                 continue;
            
//             maxFlow += minValOnPath;

//             for(int node = t; parent[node] != -1; node = parent[node]){
//                 flow[parent[node]][node] += minValOnPath;
//                 flow[node][parent[node]] -= minValOnPath;
//             }
//         }
//     }

//     out << maxFlow << '\n';
//     for(int i = 1; i <= nrLeft; ++ i) {
//         for(auto rNode : adj[i]){
//             if(rNode == s) 
//                 continue;
//             if(capacity[i][rNode] == flow[i][rNode] == 1)
//                 out << i << ' ' << rNode - nrLeft << '\n';
//         }
//     }
// }

// Solution::Solution(int _n, int _m, vector<tuple<int, int, int>> edges, int nrLeft) {
//     n = _n;
//     m = _m;
//     this->nrLeft = nrLeft;
//     adj.resize(n + 1);
//     viz.resize(n + 1);
//     parent.resize(n + 1);
//     capacity.resize(n + 1, vector<int>(n + 1, 0));
//     flow.resize(n + 1, vector<int>(n + 1, 0));

//     int x, y, c;
//     for(auto& edge : edges) {
//         x = get<0>(edge); y = get<1>(edge); c = get<2>(edge);
//         capacity[x][y] = c;
//         adj[x].push_back(y);
//         adj[y].push_back(x);
//     }
// }

// int main() {
//     vector<tuple<int, int, int>> edges;
//     int n, m, x, y, e;

//     in >> n >> m >> e;
//     while(e --) {
//         in >> x >> y;
//         edges.push_back({0, x, 1});
//         edges.push_back({x, n + y, 1});
//         edges.push_back({n + y, n + m + 1, 1});
//     }

//     Solution network(n + m + 1, e, edges, n);
//     network.findMatching(0, n + m + 1);
//     return 0;
// }


#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const char iname[] = "cuplaj.in";
const char oname[] = "cuplaj.out";

#define MAXN  20005
#define FOR(i, a, b)  for (int i = (int)(a); i <= (int)(b); ++ i)

struct list {
    int node, cap, flow;
    list *nxt, *dup;
} ;

typedef list* plist;

plist adj[MAXN], edge[MAXN];    int n, m, q[MAXN], sel[MAXN], src, sink;


void alloc_edge(plist &nou, plist &dup, int i, int j)
{
    nou = new list, dup = new list;
    nou->node = j, dup->node = i;
    nou->dup = dup, dup->dup = nou;
    nou->nxt = adj[i], dup->nxt = adj[j];
    adj[i] = nou, adj[j] = dup;
}

void read_in(void)
{
    FILE *fi = fopen(iname, "r");
    int cnt_edges, x, y;
    plist nou, dup;

    fscanf(fi, "%d %d %d", &n, &m, &cnt_edges);
    for (; cnt_edges --; )
    {
        fscanf(fi, "%d %d", &x, &y);
        alloc_edge(nou, dup, x, y + n);
        nou->cap = 1, nou->flow = dup->cap = dup->flow = 0;
    }
    fclose(fi);

    src = 0;
    FOR (i, 1, n) {
        alloc_edge(nou, dup, src, i);
        nou->cap = 1, nou->flow = dup->cap = dup->flow = 0;
    }
    sink = n+m+1;
    FOR (i, n + 1, n + m) {
        alloc_edge(nou, dup, i, sink);
        nou->cap = 1, nou->flow = dup->cap = dup->flow = 0;
    }
}

int BFS(const int src, const int sink)
{
    int h, t;
    plist it;

    memset(sel, 0, sizeof(sel));

    edge[src] = 0;
    for (sel[q[h = t = 0] = src] = 1; h <= t; ++ h)
    {
        for (it = adj[q[h]]; it; it = it->nxt)
            if ((it->cap - it->flow) > 0 && !sel[it->node])
            {
                sel[q[++ t] = it->node] = 1;
                edge[it->node] = it;
                if (it->node == sink)
                {
                    for (it = edge[sink]; it; it = edge[it->dup->node])
                        it->flow ++, it->dup->flow --;
                    return 1;
                }
            }
    }
    return 0;
}

int main(void)
{
    read_in();
    int cuplaj = 0;
    while (BFS(src, sink))  cuplaj ++;

    FILE *fo = fopen(oname, "w");
    fprintf(fo, "%d\n", cuplaj);
    FOR (i, 1, n)
    {
        for (plist it = adj[i]; it; it = it->nxt)
            if (it->flow == 1)
                fprintf(fo, "%d %d\n", i, it->node - n);
    }
    fclose(fo);

    return 0;
}