C - 2D Plane 2N Points
Time limit : 2sec / Memory limit : 256MB
Score : 400 points
Problem Statement
On a two-dimensional plane, there are N red points and N blue points. The coordinates of the i-th red point are (ai,bi), and the coordinates of the i-th blue point are (ci,di).
A red point and a blue point can form a friendly pair when, the x-coordinate of the red point is smaller than that of the blue point, and the y-coordinate of the red point is also smaller than that of the blue point.
At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.
Constraints
All input values are integers.
1≤N≤100
0≤ai,bi,ci,di<2N
a1,a2,…,aN,c1,c2,…,cN are all different.
b1,b2,…,bN,d1,d2,…,dN are all different.
Input
Input is given from Standard Input in the following format:
N
a1 b1
a2 b2
:
aN bN
c1 d1
c2 d2
:
cN dN
Output
Print the maximum number of friendly pairs.
Sample Input 1
Copy
3
2 0
3 1
1 3
4 2
0 4
5 5
Sample Output 1
Copy
2
For example, you can pair (2,0) and (4,2), then (3,1) and (5,5).
Sample Input 2
Copy
3
0 0
1 1
5 2
2 3
3 4
4 5
Sample Output 2
Copy
2
For example, you can pair (0,0) and (2,3), then (1,1) and (3,4).
Sample Input 3
Copy
2
2 2
3 3
0 0
1 1
Sample Output 3
Copy
0
It is possible that no pair can be formed.
Sample Input 4
Copy
5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7
Sample Output 4
Copy
5
Sample Input 5
Copy
5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9
Sample Output 5
Copy
4
Submit
从两个点集合选取两个点作匹配,要得到最大匹配,很显然的二分图最大匹配。跑一遍dinic即可。
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
struct point {
int a, b;
}r[105],b[105];
struct edge {
int x, f, t;
};
vector<edge> G[205];
int s, t, level[205], iter[205];
void addedge(int x,int y,int value){
G[x].push_back(edge{y,value,(int)G[y].size()});
G[y].push_back(edge{ x,0,(int)G[x].size() - 1 });
}
void bfs() {
queue<int> q;
q.push(s);
level[s] = 0;
while (!q.empty()) {
int t = q.front();
q.pop();
int siz = G[t].size();
for (int i = 0; i < siz; ++i) {
edge &p = G[t][i];
if (p.f && level[p.x] < 0) {
level[p.x] = level[t] + 1;
q.push(p.x);
}
}
}
}
int dfs(int v, int f) {
if (v == t) {
return f;
}
int s = G[v].size();
for (int &i = iter[v]; i < s; ++i) {
edge &p = G[v][i];
if (p.f && level[v] < level[p.x]) {
int d = dfs(p.x, min(p.f, f));
if (d) {
p.f -= d;
G[p.x][p.t].f += d;
return d;
}
}
}
return 0;
}
int maxflow() {
int flow = 0;
while (1) {
memset(level, -1, sizeof(level));
bfs();
if (level[t] == -1) {
return flow;
}
memset(iter, 0, sizeof(iter));
int f;
while ((f = dfs(s, INF)) > 0) {
flow += f;
}
}
}
int main() {
int n;
while (cin >> n) {
for (int i = 1; i <= n; ++i) {
cin >> r[i].a >> r[i].b;
}
for (int i = 1; i <= n; ++i) {
cin >> b[i].a >> b[i].b;
}
s = 0, t = (n << 1) + 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (r[i].a < b[j].a && r[i].b < b[j].b) {
addedge(i, j + n, 1);
}
}
}
for (int i = 1; i <= n; ++i) {
addedge(s, i, 1);
addedge(i + n, t, 1);
}
printf("%d\n", maxflow());
for (int i = 0; i <= 2 * n + 1; ++i) {
G[i].clear();
}
}
return 0;
}