Cod sursa(job #3337104)

Utilizator anto_vscAntonia Voinescu anto_vsc Data 26 ianuarie 2026 22:18:59
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstring>
#include <climits>

using namespace std;

const int N=1001;
vector <int> L[N];
int viz[N];
int flux[N][N];
int cap[N][N];
int tata[N];

//Edmond-karp
//int BFS(int s, int t){
//    memset(viz, 0, sizeof(viz));
//    memset(tata, 0, sizeof(tata));
//
//    queue<pair<int,int>> q;
//    viz[s]=1;
//    q.push({s, INT_MAX});
//
//    while(!q.empty()){
//        int nod=q.front().first;
//        int f=q.front().second;
//        q.pop();
//
//        for(auto vecin: L[nod]){
//            int rez = cap[nod][vecin] - flux[nod][vecin];
//
//            if(!viz[vecin] && rez > 0){
//                viz[vecin]=1;
//                tata[vecin]=nod;
//                int new_f = min(f, rez);
//
//                if(vecin==t){
//                    int v = t;
//                    while(v != s){
//                        int u = tata[v];
//                        flux[u][v] += new_f;
//                        flux[v][u] -= new_f;
//                        v = u;
//                    }
//                    return new_f;
//                }
//
//                q.push({vecin, new_f});
//            }
//        }
//    }
//
//    return 0;
//}
//
//
//int main(){
//    ifstream cin("maxflow.in");
//    ofstream cout("maxflow.out");
//
//    int n, m;
//    cin>>n>>m;
//
//    for(int i = 0; i < m; i++){
//        int x, y, c;
//        cin>>x>>y>>c;
//
//        L[x].push_back(y);
//        L[y].push_back(x);
//        cap[x][y]=c;
//        cap[y][x]=0;
//        flux[x][y]=0;
//        flux[y][x]=0;
//    }
//
//    int flux_max=0;
//    int s=1, t=n;
//
//    while(true){
//        int flux=BFS(s,t);
//
//        if(!flux){
//            break;
//        }
//
//        flux_max+=flux;
//    }
//
//    cout<<flux_max<<'\n';
//
//    return 0;
//}

vector <pair<int,int>> cuplaj;

void bfs(int s,int t, int n, int m){
    for(int i=s; i<=t; i++){
        viz[i]=0;
        tata[i]=0;
    }

    queue <int> q;
    q.push(s);
    viz[s]=1;

    while(!q.empty()){
        int nod=q.front();
        q.pop();
        for(auto vecin: L[nod]){
            int r=cap[nod][vecin] - flux[nod][vecin];
            if(!viz[vecin] && r>0){
                viz[vecin]=1;
                tata[vecin]=nod;
                q.push(vecin);
            }
        }
    }

    if(tata[t]!=0){
        int crr=t;
        int matched_left=-1, matched_right=-1;
        
        while(crr!=s){
            int ta=tata[crr];
            flux[ta][crr]+=1;
            flux[crr][ta]-=1;
            
            // Track bipartite edge (left partition to right partition)
            if(ta >= 1 && ta <= n && crr > n && crr <= n+m){
                matched_left = ta;
                matched_right = crr - n;
            }
            
            crr=ta;
        }
        
        if(matched_left != -1){
            cuplaj.push_back({matched_left, matched_right});
        }
    }

}


int main(){

    ifstream cin("cuplaj.in");
    ofstream cout("cuplaj.out");

    int n,m,e;
    cin>>n>>m>>e;

    for(int i=0; i<e; i++){
        int x,y;
        cin>>x>>y;
        L[x].push_back(y+n);
        L[y+n].push_back(x);
        cap[x][y+n]=1;
        cap[y+n][x]=0;
    }

    int s=0;
    int t=n+m+1;

    for(int i=1; i<=n; i++){
        L[s].push_back(i);
        cap[s][i]=1;
    }

    for(int i=n+1; i<=n+m; i++){
        L[i].push_back(t);
        cap[i][t]=1;
    }

    for(int i=0; i<n; i++){
        bfs(s,t,n,m);
    }

    if(cuplaj.size()!=m){
        cout<<"Imposibil cuplaj max."<<'\n';
    }
    else{
        for(auto p: cuplaj){
            cout<<p.first<<" "<<p.second<<'\n';
        }
    }


    return 0;
}