Cod sursa(job #2960342)

Utilizator moise_alexandruMoise Alexandru moise_alexandru Data 4 ianuarie 2023 02:16:55
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.89 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
const int maxn = 1005;
vector <int> v[maxn];
int dist[maxn];
int tata[maxn];
int sursa, destinatie;

struct muchie {
    int flux;
    int cap;
};
muchie M[maxn][maxn];

queue <int> q;
int n;

bool bfs()
{
    for(int i = 1; i <= n; i++)
        dist[i] = (1 << 30);
    dist[sursa] = 0;
    q.push(sursa);
    while(!q.empty())
    {
        int nod = q.front();
        q.pop();
        if(nod == destinatie)
            continue;
        for(auto it : v[nod])
        {
            if(dist[it] > dist[nod] + 1 && M[nod][it].flux < M[nod][it].cap)
            {
                dist[it] = dist[nod] + 1;
                tata[it] = nod;
                q.push(it);
            }
        }
    }
    if(dist[destinatie] == (1 << 30))
        return 0;
    return 1;
}

int main()
{
    int m, e;
    in >> n >> m >> e;
    int ninit = n;
    int minit = m;
    sursa = n + m + 1;
    destinatie = n + m + 2;
    for(int i = 1; i <= e; i++)
    {
        int x, y;
        in >> x >> y;
        v[x].push_back(y + n);
        v[y + n].push_back(x);
        M[x][y + n] = {0, 1};
    }
    for(int i = 1; i <= n; i++)
    {
        v[sursa].push_back(i);
        v[i].push_back(sursa);
        M[sursa][i] = {0, 1};
    }
    for(int i = 1; i <= m; i++)
    {
        v[i + n].push_back(destinatie);
        v[destinatie].push_back(i + n);
        M[i + n][destinatie] = {0, 1};
    }
    n = n + m + 2;
    while(bfs())
    {
        for(auto vec : v[destinatie])
        {
            if(dist[vec] == (1 << 30) || M[vec][destinatie].flux == M[vec][destinatie].cap)
                continue;
            tata[destinatie] = vec;
            int act = destinatie;
            vector <int> drum;
            while(tata[act] != 0)
            {
                drum.push_back(act);
                act = tata[act];
            }
            drum.push_back(act);
            reverse(drum.begin(), drum.end());
            int topush = (1 << 30);
            for(int i = 0; i < drum.size() - 1; i++)
                topush = min(topush, M[drum[i]][drum[i + 1]].cap - M[drum[i]][drum[i + 1]].flux);
            for(int i = 0; i < drum.size() - 1; i++)
            {
                M[drum[i]][drum[i + 1]].flux += topush;
                M[drum[i + 1]][drum[i]].flux -= topush;
            }
        }
    }
    int sol = 0;
    for(auto it : v[sursa])
        sol = sol + M[sursa][it].flux;
    out << sol << "\n";
    for(int i = 1; i <= ninit; i++)
    {
        for(int j = ninit + 1; j <= ninit + minit; j++)
        {
            if(M[i][j].flux == 1)
            {
                out << i << " " << j - ninit << "\n";
            }
        }
    }
    return 0;
}