-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmatching-2.cpp
126 lines (116 loc) · 2.48 KB
/
matching-2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include"iomanip"
#include"iostream"
#include"limits"
#include"cmath"
#include"vector"
#include"algorithm"
#include"list"
#include"queue"
#include"stack"
#include"set"
#include"unordered_set"
#include"map"
#include"unordered_map"
#include"string"
#include"cstring"
#include"assert.h"
using namespace std;
#define ff first
#define ss second
#define all(v) v.begin(),v.end()
#define mp make_pair
#define pb push_back
#define mset(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long long LL;
struct Edge {
int u, v;
LL cap, flow;
Edge() {}
Edge(int u, int v, LL cap): u(u), v(v), cap(cap), flow(0) {}
};
struct Dinic {
int N;
vector<Edge> E;
vector<vector<int>> g;
vector<int> d, pt;
Dinic(int N): N(N), E(0), g(N), d(N), pt(N) {}
void AddEdge(int u, int v, LL cap) {
if (u != v) {
E.emplace_back(u, v, cap);
g[u].emplace_back(E.size() - 1);
E.emplace_back(v, u, 0);
g[v].emplace_back(E.size() - 1);
}
}
bool BFS(int S, int T) {
queue<int> q({S});
fill(d.begin(), d.end(), N + 1);
d[S] = 0;
while(!q.empty()) {
int u = q.front(); q.pop();
if (u == T) break;
for (int k: g[u]) {
Edge &e = E[k];
if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
d[e.v] = d[e.u] + 1;
q.emplace(e.v);
}
}
}
return d[T] != N + 1;
}
LL DFS(int u, int T, LL flow = -1) {
if (u == T || flow == 0) return flow;
for (int &i = pt[u]; i < g[u].size(); ++i) {
Edge &e = E[g[u][i]];
Edge &oe = E[g[u][i]^1];
if (d[e.v] == d[e.u] + 1) {
LL amt = e.cap - e.flow;
if (flow != -1 && amt > flow) amt = flow;
if (LL pushed = DFS(e.v, T, amt)) {
e.flow += pushed;
oe.flow -= pushed;
return pushed;
}
}
}
return 0;
}
LL MaxFlow(int S, int T) {
LL total = 0;
while (BFS(S, T)) {
fill(pt.begin(), pt.end(), 0);
while (LL flow = DFS(S, T))
total += flow;
}
return total;
}
};
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n,m,p;
cin>>n>>m>>p;
Dinic ob(n+m+2);
for(int i=0;i<p;++i)
{
int x,y;
cin>>x>>y;
ob.AddEdge(x,n+y,1);
}
for(int i=1;i<=n;++i)
{
ob.AddEdge(0,i,1);
}
for(int i=1;i<=m;++i)
{
ob.AddEdge(n+i,n+m+1,1);
}
ll ans = ob.MaxFlow(0,n+m+1);
cout<<ans<<'\n';
}