Cod sursa(job #2961381)

Utilizator razvan1403razvan razvan1403 Data 6 ianuarie 2023 13:39:42
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.38 kb
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define d double
#define in int
#define si(x) scanf('%d', &x)
#define sl(x) scanf('%lld', &x)
#define ss(s) scanf('%s', s) 
#define pi(x) printf('%d', x)
#define pl(x) printf('%lld', x)
#define ps(s) printf('%s', s) 
#define pb push_back 
#define mp make_pair 
#define F first 
#define S second 
#define all(x) x.begin(), x.end() 
#define clr(x) memset(x, 0, sizeof(x))
#define sortall(x) sort(all(x)) 
typedef pair<int, int> pii; 
typedef pair<ll, ll> pl; 
typedef vector<int> vi; 
typedef vector<ll> vl; 
#define modulo 1000000007
#define FOR(i,a,b) for(int i=a;i<=b;i++)
typedef vector<pii> vpii;

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

struct info{
  int start, stop, cap, poz;
};

int n,m, e, totalNoduri, totalMuchii, start, final;
int fluxCurent, total;
int x,y;

vector<vector<int>> graf;
vector<info> muchii;
vector<int> vizitat, nod_flux;

void add(int a, int b){
  info mc;
  graf[b].push_back(totalMuchii + 1);
  mc.start = a;
  mc.stop = b;
  mc.cap = 1;
  mc.poz = totalMuchii + 1;
  muchii.push_back(mc);

  graf[a].push_back(totalMuchii);
  mc.start = b;
  mc.stop = a;
  mc.cap = 0;
  mc.poz = totalMuchii;
  muchii.push_back(mc);
  totalMuchii += 2;
}

void solve(){
  fin>>n>>m>>e;
  totalNoduri = n + m + 2;
  start = 0;
  final = totalNoduri - 1;
  graf = vector<vector<int>>(totalNoduri);
  for(int i=1;i<=e;i++){
    fin>>x>>y;
    add(x, y+n);
  }
  // legam nodurile la sursa
  for(int i=1;i<=n;i++){
    add(start, i);
  }
  // legam nodurile la destinatie
  for(int i=n+1;i<totalNoduri-1;i++){

    add(i, final);
  }
}

int bfs(){
  nod_flux = vector<int>(totalNoduri, 0);
  vizitat = vector<int>(totalNoduri, 0);
  queue<int> coada;
  coada.push(start);
  vizitat[start] = true;
  while (!coada.empty())
  {
    int nod = coada.front();
    coada.pop();
    if (nod != final)
    {
      for (auto el : graf[nod])
      {
        info mc = muchii[el];
        if (vizitat[mc.stop] == false && mc.cap > 0)
        {
            nod_flux[mc.stop] = el;
            coada.push(mc.stop);
            vizitat[mc.stop] = true;
        }
      }
    }
  }
  return vizitat[final];
}

int main() 
{
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int t = 1;

  while(t--){
    solve();
  }

  while (bfs())
    {
      for (auto el : graf[final])
      {
        if (vizitat[muchii[el].stop] && muchii[muchii[el].poz].cap > 0)
        {
          fluxCurent = INT_MAX;
          info mc = muchii[el];
          nod_flux[final] = mc.poz;
          int nod = final;
          while (nod != start)
          {
              fluxCurent = min(fluxCurent, muchii[nod_flux[nod]].cap);
              nod = muchii[nod_flux[nod]].start;
          }
          nod = final;
          while (nod != start)
          {
              muchii[muchii[nod_flux[nod]].poz].cap += fluxCurent;
              muchii[nod_flux[nod]].cap -= fluxCurent;
              nod = muchii[nod_flux[nod]].start;
          }
          total += fluxCurent;
        }
      }
    }

  fout<<total<<endl;
  for(info muchie: muchii){
    if(muchie.start < muchie.stop && muchie.start != 0  && muchie.stop != final && muchie.cap == 0)
    {
      fout<<muchie.start<<" "<<muchie.stop - n<<endl;
    }
  }

  return 0;
}