Cod sursa(job #2685980)

Utilizator RNedelcuNedelcu Radu RNedelcu Data 18 decembrie 2020 11:03:51
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <iostream>
#include <bits/stdc++.h>
#define MAX 10003
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
int N,M,E; // Card multimea 1, card multimea 2, nr muchii
vector<int> Graph[MAX];
int capacitate[MAX][MAX];
int flow[MAX][MAX];
int start,sink;
int bfs(vector<int> &tata)
{
    fill(tata.begin(),tata.end(),-1);
    pair<int,int> que[MAX]; //Nod, flow
    int L=1;
    que[L]= {start,2e9};
    tata[start]=start;
    for(int i=1; i<=L; i++)
    {
        int cur = que[i].first;
        int curFlow = que[i].second;
        for(auto next : Graph[cur])
        {
            if(tata[next] == -1 && (capacitate[cur][next]-flow[cur][next]>0)) // Daca nu e deja vizitat si mai putem creste fluxul
            {
                //
                tata[next] = cur;
                int new_flow = min(curFlow,capacitate[cur][next]-flow[cur][next]);
                if(next==sink)
                    return new_flow;
                que[++L]= {next,new_flow};
            }
        }
    }
    return 0;
}

int main()
{
    int x,y,z,t;
    in>>N>>M>>E;
    start = N+M+1;
    sink = M+N+2;
    for(int i=1;i<=N;i++)
    {
        capacitate[start][i]=1;
        Graph[start].push_back(i);
        Graph[i].push_back(start);
    }
    for(int i=1;i<=M;i++)
    {
         capacitate[N+i][sink]=1;
        Graph[N+i].push_back(sink);
        Graph[sink].push_back(N+i);
    }
    for(int i=1; i<=E; i++)
    {
        in>>x>>y; //Nod, Nod, capacitatea maxima, capacitatea folosita
        Graph[x].push_back(y+N);
        Graph[y+N].push_back(x);
        capacitate[x][y+N] = 1;
    }
    int maxflow = 0;
    vector<int> tata(N+M+3);
    int new_flow;
    while(new_flow = bfs(tata)) //Cat timp gasim un lant nesaturat
    {
        maxflow+=new_flow; //Crestem fluxul
        int current = sink;
        while(current!=start) //Updatam capacitatile
        {
            int previous = tata[current];
            flow[previous][current]+=new_flow; // Pe muchiile directe adun fluxul adaugat
            flow[current][previous]-=new_flow; // Pe muchiile inverse scad
            current = previous;
        }
    }
    out<<maxflow<<endl;
            for(int i=1;i<=N;i++)
            for(auto j : Graph[i])
            if(flow[i][j]>0)
                out<<i<<" "<<j-N<<"\n";
    return 0;
}