Cod sursa(job #2960198)

Utilizator Mike07Mihai-Alexandru Militaru Mike07 Data 3 ianuarie 2023 18:36:17
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.33 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;
//            parrent[t]=node;
//            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;
//}


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

int nodes, edges, s, t, leftt, rightt;
vector<vector<pair<int, pair<int, int>>>> graphh;
vector<pair<int, int>> parrent;

void addedge(int x, int y){
    graphh[x].push_back({y, {1,graphh[y].size()}});
    graphh[y].push_back({x, {0,graphh[x].size()-1}});

}


void read(){
    fin>>leftt>>rightt>>edges;
    nodes=leftt+rightt;

    graphh.resize(nodes+3);
    parrent.resize(nodes+3);

    for(int i=0;i<edges;i++){
        int x,y;
        fin>>x>>y;
        addedge(x,y+leftt);

    }

    for(int i=1;i<=leftt;i++){
        addedge(0,i);
    }

    for(int i=leftt+1;i<=leftt+rightt;i++) {
        addedge(i,nodes+1);
    }
    s=0;
    t=nodes+1;

}

bool bfs(){
    vector <bool> viz(nodes+3);
    queue<int> q;
    q.push(s);
    viz[s]=true;
    parrent[s]={-1,-1};
    while(!q.empty()){
        int current_node = q.front();
        q.pop();
        int i=0;
        if(current_node==t){
            continue;
        }
        for(auto adj: graphh[current_node]){
            int c=adj.second.first;
            int adj_node=adj.first;
            if(!viz[adj_node] && c){
                parrent[adj_node]={current_node, i};
                if(adj_node==t){
                    return true;
                }
                viz[adj_node]=true;
                q.push(adj_node);
            }
            i++;
        }
    }
    return false;
}

int edmondsKarp(){
    long flux_max=0;
    while(bfs()){
        int x=t, path_min=1;
        while(parrent[x].first!=-1){
            int u=parrent[x].first;
            int v=parrent[x].second;
            path_min=min(path_min, graphh[u][v].second.first);
            x=parrent[x].first;
        }
        x=t;
        while(parrent[x].first!=-1){
            int u=parrent[x].first;
            int v=parrent[x].second;
            int w=graphh[u][v].second.second;
            graphh[u][v].second.first-=path_min;
            graphh[x][w].second.first+=path_min;
            x=parrent[x].first;
        }
        flux_max += path_min;

    }
    return flux_max;
}

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