Cod sursa(job #2601384)

Utilizator Stefan_PiscuPiscu Stefan Constantin Stefan_Piscu Data 14 aprilie 2020 13:32:36
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>
using namespace std;

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

int n, m, nre;

struct edge{
  int from, to, flow, cap;
  edge(int c, int a, int b){
    from=c, to=a, flow=0, cap=b;
  }
};

vector<edge> edges;

struct node{
  int level, ptr;
  vector<int> vec;
  node(){
    level=0;
    ptr=0;
  }
};

int s, d;
vector<node> g;

void addedge(int a, int b, int c){
  edge x(a, b, c), y(b, a, 0);
  g[a].vec.push_back(edges.size());
  edges.push_back(x);
  g[b].vec.push_back(edges.size());
  edges.push_back(y);
}

bool bfs(int s){
  for(int i=1;i<g.size();++i){
    g[i].level=-1;
    g[i].ptr=0;
  }
  g[s].level=0;
  queue<int> q;
  q.push(s);
  while(!q.empty()){
    int nod=q.front();
    q.pop();
    for(auto i:g[nod].vec){
      int dest=edges[i].to;
      if(g[dest].level!=-1||edges[i].cap<=edges[i].flow) continue;
      q.push(dest);
      g[dest].level=g[nod].level+1;
    }
  }
  return g[d].level!=-1;
}

int dfs(int nod, int pushed){
  if(pushed==0) return 0;
  if(nod==d) return pushed;
  for(int &i=g[nod].ptr;i<g[nod].vec.size();++i){
    int e=g[nod].vec[i];
    if((g[edges[e].to].level==g[nod].level+1)&&(edges[e].cap-edges[e].flow>0)){
      int sent=dfs(edges[e].to, min(edges[e].cap-edges[e].flow, pushed));
      if(sent==0) continue;
      edges[e].flow+=sent;
      edges[e^1].flow-=sent;
      return sent;
    }
  }
  return 0;
}

int getflow(){
  int sol=0;
  while(bfs(s)){
    while(long long pushed=dfs(s, (1<<30))){
      sol+=pushed;
    }
  }
  return sol;
}

int main()
{
  fin>>n>>m>>nre;
  g.resize(n+m+3);
  s=1, d=n+m+2;
  for(int i=1;i<=nre;++i){
    int a, b;
    fin>>a>>b;
    addedge(a+1, n+b+1, 1);
  }
  for(int i=1;i<=n;++i){
    addedge(s, i+1, 1);
  }
  for(int i=1;i<=m;++i){
    addedge(i+n+1, d, 1);
  }
  fout<<getflow()<<"\n";
  for(int i=0;i<2*nre;++i){
    if(edges[i].flow==1){
      fout<<edges[i].from-1<<" "<<edges[i].to-n-1<<"\n";
    }
  }
  return 0;
}