Cod sursa(job #2494788)

Utilizator MoldovanAndrei1Moldovan Andrei MoldovanAndrei1 Data 18 noiembrie 2019 14:16:58
Problema Cuplaj maxim in graf bipartit Scor 48
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include<bits/stdc++.h>
using namespace std;

    ofstream fout("cuplaj.out");
int m,n;
struct dd
{
    int x,y;
};
dd v[100005];
int cnt=0;
struct Dinic {
	struct Edge {
		int flow, to, next;
	};
	vector <Edge> edges;
	vector <int> adia, at, dist;
	int S, D;

	void addEdge(int from, int to, int cap) {
       //fout<<"capacity "<<cap<<" from "<<from<<" to "<<to<<endl;
       edges.push_back({ cap, to, adia[from] });
		//fout<<"edges"<<edges.size()-1<<"={"<<cap<<","<<to<<","<<adia[from]<<"}"<<endl;
		adia[from] = edges.size() - 1;
		edges.push_back({ 0, from, adia[to] });

		//fout<<"edges"<<edges.size()-1<<"={"<<0<<","<<from<<","<<adia[to]<<"}"<<endl;
		adia[to] = edges.size() - 1;
	}

	bool bfs() {
		queue <int> q;
		fill(dist.begin(), dist.end(), 1e9);
		dist[S] = 0;
		q.push(S);
		while (!q.empty()) {
			int x = q.front();
			q.pop();

			for (int i = adia[x]; i != -1; i = edges[i].next) {
				if (dist[edges[i].to] > dist[x] + 1 && edges[i].flow) {
					dist[edges[i].to] = 1 + dist[x];
					q.push(edges[i].to);
				}
			}
		}
		return dist[D] < 1e9;
	}
	int dfs(int nod, int fmax) {
		if (nod == D)
			return fmax;
		while (at[nod] != -1) {
			Edge& e = edges[at[nod]];
			int f;
			if (dist[e.to] == dist[nod] + 1 && e.flow && (f = dfs(e.to, min(fmax, e.flow)))) {
				e.flow -= f;
				if(e.to!=(m+n+1)&&nod!=0&&(e.to!=0&&nod!=(m+n+1)))v[++cnt].x=min(nod,e.to),v[cnt].y=max(nod,e.to);
				edges[at[nod] ^ 1].flow += f;
				return f;
			}
			at[nod] = edges[at[nod]].next;
		}
		return 0;
	}

	int GetFlow() {
		int f = 0;
		while (bfs()) {
			at = adia;
			while (int x = dfs(S, 1e9))
				f += x;
		}
		return f;
	}
	Dinic(int n , int s , int d)  {
		S = s, D = d;
		at = dist = adia = vector <int>(n + 1, -1);
	}
};
int main()
{
    freopen("cuplaj.in","r",stdin);
    int muchii;
    int a,b;
    cin>>m>>n>>muchii;
 Dinic g(m+n+2,0,m+n+1);
    for(int i=1;i<=muchii;i++)
    {
        cin>>a>>b;
        g.addEdge(a,m+b,1);
    }
    for(int i=1;i<=m;i++)
        g.addEdge(0,i,1);
    for(int i=1;i<=n;i++)
        g.addEdge(m+i,m+n+1,1);
    int res=g.GetFlow();
    fout<<res<<"\n";
    for(int i=1;i<=cnt;i++)fout<<v[i].x<<" "<<v[i].y-m<<"\n";
}