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
| #include <cstdio>
#include <queue>
using namespace std;
const int INF = 1009999999;
inline int getint() {
int r = 0, k = 1; char c = getchar();
for (; c < '0' || c > '9'; c = getchar()) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
return r * k;
}
int n, S, T;
namespace MinCost {
const int maxn = 1005;
const int maxnode = maxn*2+10;
const int maxe = 80010;
struct edge_type { int to, next, r, c; } edge[maxe];
int h[maxnode], cnte = 1;
void ins(const int u, const int v, const int f, const int c) {
++cnte; edge[cnte].to = v; edge[cnte].next = h[u]; edge[cnte].r = f; edge[cnte].c = c; h[u] = cnte;
++cnte; edge[cnte].to = u; edge[cnte].next = h[v]; edge[cnte].r = 0; edge[cnte].c = -c; h[v] = cnte;
}
queue<int> Q;
int dis[maxnode], pre[maxnode], a[maxnode], ans = 0;
bool vis[maxnode];
inline bool SPFA(){
while (!Q.empty()) Q.pop();
for (int i = S; i <= T; ++i) vis[i] = false, dis[i] = INF;
dis[S] = 0; Q.push(S); a[S] = INF; pre[S] = 0;
int now;
while (!Q.empty()) {
now = Q.front(); Q.pop();
vis[now] = false;
for (int i = h[now]; i; i = edge[i].next) {
if (edge[i].r && dis[edge[i].to] > dis[now] + edge[i].c) {
dis[edge[i].to] = dis[now] + edge[i].c;
pre[edge[i].to] = i;
a[edge[i].to] = min(a[now], edge[i].r);
if (!vis[edge[i].to]) {
Q.push(edge[i].to);
vis[edge[i].to] = true;
}
}
}
}
if (dis[T] == INF) return false;
ans += a[T] * dis[T];
for (now = T; now != S; now = edge[pre[now]^1].to) {
edge[pre[now]].r -= a[T];
edge[pre[now]^1].r += a[T];
}
return true;
}
inline void MCMF() {
ans = 0;
while (SPFA());
}
}
int A, B, X[233], Y[233], H[100005], tot, V[233][233];
int main() {
n = getint();
for (int i = 1; i <= n; ++i) {
A = getint();
if (!H[A]) H[A] = ++tot;
A = H[A]; ++X[A];
B = getint();
if (!H[B]) H[B] = ++tot;
B = H[B]; ++Y[B];
V[A][B] = 1;
}
S = 0; T = 222;
for (int i = 1; i <= 100; ++i) {
if (X[i]) MinCost::ins(S, i, X[i], 0);
if (Y[i]) MinCost::ins(i + 101, T, Y[i], 0);
}
for (int i = 1; i <= 100; ++i)
if (X[i])
for (int j = 1; j <= 100; ++j)
if (Y[j])
MinCost::ins(i, j + 101, 1, V[i][j]);
MinCost::MCMF();
printf("%d", MinCost::ans);
}
|