Cod sursa(job #2961741)

Utilizator TeoDiDiaconescu Teodora TeoDi Data 6 ianuarie 2023 22:03:36
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>
#define oo 1e9

using namespace std;

vector<vector<int> > cap;
vector<vector<vector<int> > > muchie;
vector<int> nivel;
int n, t;
int max_flow;

bool BFSMF(int act){
    bool ok = false;
    queue<pair<int, int> > q;
    q.push({act,0});
    nivel[act] = 0;
    while(!q.empty()){
        int nct = q.front().first;
        int nv = q.front().second;
        if(nct == t) ok = true;
        q.pop();
        for(auto j:muchie[nct]){
            if(nivel[j[0]] == -1 && j[1] && !j[2]){
                q.push({j[0],nv+1});
                nivel[j[0]] = nv + 1;
            }
        }
    }
    return ok;
}

int DFSMF(int act, int cost){
    if(act == t) return cost;
    int ctactm = -1;
    for(auto j:muchie[act]){
        ctactm++;
        if(j[2] == 0 && j[1] != 0 && (nivel[j[0]] - nivel[act] == 1) && !j[2]) {
            int ct = min(cost, j[1]);
            ct = DFSMF(j[0], ct);
            if (ct == -1) j[2] = 1;
            else {
                muchie[act][ctactm][1] -= ct;
                muchie[j[0]].push_back({act, ct, 0});
                return ct;
            }
        }
    }
    return -1;
}

int MaxFlow(int y, int s, int ti){
    t = ti;
    /*muchie.assign(n, {});
    for(auto j:cap){
        muchie[j[0]].push_back({j[1], j[2], 0});
    }*/
    max_flow = 0;
    while(true){
        nivel.assign(n, -1);
        bool ok = false;
        queue<pair<int, int> > q;
        q.push({s,0});
        nivel[s] = 0;
        while(!q.empty()){
            int nct = q.front().first;
            int nv = q.front().second;
            if(nct == t) ok = true;
            q.pop();
            for(auto j:muchie[nct]){
                if(nivel[j[0]] == -1 && j[1] && !j[2]){
                    q.push({j[0],nv+1});
                    nivel[j[0]] = nv + 1;
                }
            }
        }
        if(!ok) return max_flow;
        int flow = 0;
        do{
            flow = DFSMF(s, oo);
            if(flow != -1)
                max_flow += flow;
        }while(flow != -1);
    }
}

//// optimisation of MaxFlow
int MaxFlow(int s, int ti){
    t = ti;
    max_flow = 0;
    while(true){
        nivel.assign(n, -1);
        bool ok = BFSMF(s);
        if(!ok) return max_flow;
        int flow = 0;
        do{
            flow = DFSMF(s, oo);
            if(flow != -1)
                max_flow += flow;
        }while(flow != -1);
    }
}

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

int main() {
    int n1, n2, m;
    fin >> n1 >> n2 >> m;
    n = n1 + n2 + 2;
    muchie.assign(n, {});
    for(int i = 0; i < m; i++){
        int x, y, c;
        fin >> x >> y;
        muchie[x].push_back({y + n1, 1, 0});
    }
    for(int i = 1; i <= n1; i++){
        muchie[0].push_back({i, 1, 0});
    }
    for(int i = n1+1; i <= n1+n2; i++){
        muchie[i].push_back({n-1, 1, 0});
    }
    fout<<MaxFlow(0, n-1);
    return 0;
}