Cod sursa(job #2957160)

Utilizator AACthAirinei Andrei Cristian AACth Data 21 decembrie 2022 19:34:35
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
#define cin f
#define cout g
// #define int long long
const int Max = 1e5 + 1;
void nos()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
}
#define pb push_back
const int INF = 1e9;

struct Edge {
    int x;
    int flow;
    int cap;
    int nxt;
};

struct Dinic {
    int source;
    int sink;
    int n;
    vector <vector <Edge>> gr;
    vector <int> dist;
    vector <int> start;
    Dinic (int _source, int _sink, int _size) {
        source = _source;
        sink = _sink;
        n = _size;
        gr.resize (_size + 1);
        dist.resize (_size + 1);
        start.resize (_size + 1);
    }
    void add_edge (int x, int y, int cap) {
        // cout<<x<<' '<<y<<'\n';
        gr[x].pb ({y, 0, cap, (int)gr[y].size ()});
        gr[y].pb ({x, 0, 0, (int)gr[x].size () - 1});
    }
    bool bfs () {
        for (int i = 1; i <= n; i++)
            dist[i] = -1;
        dist[source] = 0;
        queue <int> q;
        q.push (source);
        while (q.size ()) {
            int node = q.front ();
            q.pop ();
            for (auto vec : gr[node]) {
                if (dist[vec.x] == - 1 && vec.cap > vec.flow) {
                    dist[vec.x] = dist[node] + 1;
                    q.push (vec.x);
                }
            }
        }
        return dist[sink] != -1;
    }
    int dfs (int node, int sink, int flow) {
        if (node == sink)
            return flow;
        while (start[node] < gr[node].size ()) {
            Edge e = gr[node][start[node]];
            if (dist[e.x] == dist[node] + 1 && e.flow < e.cap) {
                int new_flow = dfs (e.x, sink, min (flow, e.cap - e.flow));
                if (new_flow > 0) {
                    gr[node][start[node]].flow += new_flow;
                    gr[e.x][e.nxt].flow -= new_flow;
                    return new_flow;
                }
            }
            start[node]++;
        }
        return 0;
    }
    int maxflow () {
        int ans = 0;
        while (bfs ()) {
            int flow;
            for (auto &x : start) x = 0;
            while (flow = dfs (source, sink, INF)){
                ans += flow;
            }
        }
        return ans;
    }
};
int n,m,k;
void read()
{
	
}
void solve()
{
	f>>n>>m>>k;
	Dinic flow(0,n+m+1,n+m+1);
	for(int i=0;i<k;i++)
	{
		int n1,n2;
		f>>n1>>n2;
		flow.add_edge(n1,n2+n,1);
	}
    for(int i=1;i<=n;i++)
        flow.add_edge(0,i,1);
    for(int i=1;i<=m;i++)
        flow.add_edge(i+n,n+m+1,1);
	cout << flow.maxflow();
    
}
void restart()
{

}
int32_t main()
{
    nos();
    // int teste;
    // f>>teste;
    // while(teste--)
    {
        read();
        solve();
        restart();
    }
    return 0;
}