Cod sursa(job #2960227)

Utilizator Mike07Mihai-Alexandru Militaru Mike07 Data 3 ianuarie 2023 19:39:18
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("cuplaj.in");
ofstream g("cuplaj.out");

int leftSize, rightSize, edges, s, t;
vector<bool> existingRight;
vector<pair<int, int>> parrent, rightnodes;
vector<vector<pair<int, pair<int, int>>>> graph;

void addedge(int x, int y){
    graph[x].push_back({y, {1,graph[y].size()}});
    graph[y].push_back({x, {0,graph[x].size()-1}});
    if(y==t){
        rightnodes.emplace_back(x, graph[x].size()-1);
    }
}

void read(){
    f >> leftSize >> rightSize >> edges;
    s = 0;
    t = leftSize+rightSize+1;
    existingRight.resize(rightSize+1);
    parrent.resize(t+1);
    graph.resize(t+1);
    for(int i = 1; i <= leftSize; i++)
        addedge(s, i);

    for(int i = 1; i <= edges; i++){
        int x, y;
        f>> x >> y;
        addedge(x, leftSize + y);
        existingRight[y] = true;
    }
    for(int i = 1; i <= rightSize; i++)
        if(existingRight[i])
            addedge(leftSize+i, t);
}


bool bf(){
    vector<bool> visited(t+1);
    queue<int> q;
    q.push(s);
    visited[s] = true;
    parrent[s] = {-1, -1};

    while(!q.empty()){
        int current_node=q.front();
        q.pop();
        if(current_node == t){
            continue;
        }
        int i=0;
        for(auto node: graph[current_node]){
            int c=node.second.first;
            int adj_node=node.first;
            if(!visited[adj_node] && c){
                parrent[adj_node]={current_node, i};
                visited[adj_node]=true;
                q.push(adj_node);
            }
            i++;

        }
    }
    return visited[t];
}

long long int cuplaj(){
    long long int maxflow=0;
    while(bf()){
//        for (auto node: rightnodes){
            int min_path = 1;

            int y=t;
            while(parrent[y].first!=-1){
                int u = parrent[y].first;
                int v = parrent[y].second;
                min_path=min(min_path, graph[u][v].second.first);
                y=u;
            }
            y=t;
            while(parrent[y].first!=-1){
                int u = parrent[y].first;
                int v = parrent[y].second;
                int w = graph[u][v].second.second;
                graph[u][v].second.first-=min_path;
                graph[y][w].second.first+=min_path;
                y=u;
            }
            maxflow += min_path;


    }
    return maxflow;
}

int main(){
    read();
    g << cuplaj() << '\n';
    for(int u = 1; u <= leftSize; u++)
        for(auto node: graph[u]){
            int v, c;
            v = node.first;
            c = node.second.first;
            if(v && c == 0 && v != t)
                g << u << " " << v-leftSize << '\n';
        }
    return 0;
}