Skip to content

Commit f355ee2

Browse files
committed
使用ISAP算法进行二分图匹配(附UOJ - 78 二分图最大匹配代码)
1 parent 10ba4fb commit f355ee2

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <cstdio>
2+
3+
#define INF 1000000000
4+
5+
using namespace std;
6+
7+
struct vertex
8+
{
9+
int first, dis;
10+
}V[1010];
11+
12+
struct edge
13+
{
14+
int endp, next, flow;
15+
}E[502010];
16+
17+
int nl, nr, iec, ec = 2, src = 1005, sink = 1006, gap[1010];
18+
19+
inline int min(int x, int y)
20+
{
21+
return x < y ? x : y;
22+
}
23+
24+
void init()
25+
{
26+
gap[0] = nl + nr + 2;
27+
}
28+
29+
void add_edge(int u, int v, int f)
30+
{
31+
E[ec].next = V[u].first;
32+
V[u].first = ec;
33+
E[ec].endp = v;
34+
E[ec].flow = f;
35+
ec++;
36+
}
37+
38+
int isap(int u, int curf)
39+
{
40+
if (u == sink)
41+
{
42+
return curf;
43+
}
44+
int totalf = 0, mindis = nl + nr + 2;
45+
for (int cur = V[u].first; cur != 0 && totalf < curf; cur = E[cur].next)
46+
{
47+
if (E[cur].flow > 0)
48+
{
49+
if (V[u].dis == V[E[cur].endp].dis + 1)
50+
{
51+
int f = isap(E[cur].endp, min(curf - totalf, E[cur].flow));
52+
E[cur].flow -= f;
53+
E[cur ^ 1].flow += f;
54+
totalf += f;
55+
}
56+
if (V[E[cur].endp].dis < mindis)
57+
{
58+
mindis = V[E[cur].endp].dis;
59+
}
60+
}
61+
}
62+
if (totalf == 0)
63+
{
64+
if (--gap[V[u].dis] == 0) V[src].dis = nl + nr + 2;
65+
V[u].dis = mindis + 1;
66+
gap[V[u].dis]++;
67+
}
68+
return totalf;
69+
}
70+
71+
int max_flow()
72+
{
73+
int res = 0;
74+
while (V[src].dis < nl + nr + 2)
75+
{
76+
res += isap(src, INF);
77+
}
78+
return res;
79+
}
80+
81+
int main()
82+
{
83+
int u, v;
84+
scanf("%d%d%d", &nl, &nr, &iec);
85+
for (int i = 0; i < iec; i++)
86+
{
87+
scanf("%d%d", &u, &v);
88+
add_edge(u, v + nl, 1);
89+
add_edge(v + nl, u, 0);
90+
}
91+
for (int i = 1; i <= nl; i++)
92+
{
93+
add_edge(src, i, 1);
94+
add_edge(i, src, 0);
95+
}
96+
for (int i = 1; i <= nr; i++)
97+
{
98+
add_edge(i + nl, sink, 1);
99+
add_edge(sink, i + nl, 0);
100+
}
101+
init();
102+
printf("%d\n", max_flow());
103+
for (int i = 1; i <= nl; i++)
104+
{
105+
bool has = false;
106+
for (int cur = V[i].first; cur != 0; cur = E[cur].next)
107+
{
108+
if (E[cur].endp != src && E[cur].flow == 0)
109+
{
110+
printf("%d ", E[cur].endp - nl);
111+
has = true;
112+
break;
113+
}
114+
}
115+
if (has == false)
116+
{
117+
printf("0 ");
118+
}
119+
}
120+
return 0;
121+
}

0 commit comments

Comments
 (0)