Cod sursa(job #2957960)

Utilizator ViAlexVisan Alexandru ViAlex Data 23 decembrie 2022 21:38:32
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
#include<iostream>
#include<algorithm>
#include<vector>
#include<fstream>
#include<queue>
using namespace std;

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

struct edge{
	int from, to, capacity;
	edge * reverse;
};

const int mx = 20100;
const int inf = 1e9;

vector<edge*> g[mx];
vector<edge*> edges;
// adjacent to the final node
vector<edge*> adjacent;
vector<edge*> parent;
int n,m,e;
int s,t;

void add_edge(int a,int b){
	edge* p = new edge();
	edge* q = new edge();

	p->from = a;
	p->to= b;
	p->capacity = 1;
	p->reverse = q;

	q->from = b;
	q->to= a;
	q->capacity = 0;
	q->reverse = p;
	g[a].push_back(p);
	g[b].push_back(q);

	edges.push_back(p);
	edges.push_back(q);
	if(b==t){
		adjacent.push_back(p);
	}
}

void read(){

	in>>n>>m>>e;
	s = 1;
	t = 2 + n + m;

	int a,b;
	for(int i=0;i<e;i++){
		in>>a>>b;

		a = a + 1;
		b = b + n + 1;
		add_edge(a,b);
	}

	for(int i=1;i<=n;i++){
		add_edge(s, 1+i);	
	}

	for(int i=1;i<=m;i++){
		add_edge(i+n+1, t);
	}
}

bool flow(){
	parent = vector<edge*>(mx,nullptr);
	queue<int> q;
	q.push(s);

	while(!q.empty()){
		int here = q.front();
		q.pop();

		if(here == t){
			continue;
		}

		for(edge*e : g[here]){
			if(parent[e->to] == nullptr && e->capacity!=0){
				parent[e->to] = e;	
				q.push(e->to);
			}
		}
	}
	return parent[t]!=nullptr;
}


void solve(){

	int total_flow = 0;

	while(flow()){
		for(edge* x: adjacent){
			if(parent[x->from] == nullptr || x->capacity == 0){
				continue;
			}
			parent[t] = x;	
			int now = t, cflow = inf;

			while(now!=s){
				cflow = min(cflow, parent[now]->capacity);
				now = parent[now] -> from;
			}
			now = t;
			while(now!=s){
				parent[now] -> capacity -= cflow;
				parent[now] -> reverse -> capacity += cflow;
				now = parent[now] -> from;
			}
			total_flow+=cflow;
		}
	}
	out<<total_flow<<'\n';

	for(const edge*x : edges){
		if(x->from !=s && x->to != t && x->from < x->to && x->capacity == 0){
			out<<x->from - 1<<" "<<x->to - n - 1<<'\n';
		}	
	}
}



int main(){
	read();
	solve();

	return 0;
}