Problem:
 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 (a_i, b_i) , and the coordinates of the i -th blue point are (c_i, d_i) .  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 \leq N \leq 100  0 \leq a_i, b_i, c_i, d_i < 2N  a_1, a_2, ..., a_N, c_1, c_2, ..., c_N are all different.  b_1, b_2, ..., b_N, d_1, d_2, ..., d_N are all different.         Input Input is given from Standard Input in the following format:  N  a_1  b_1  a_2  b_2  :  a_N  b_N  c_1  d_1  c_2  d_2  :  c_N  d_N       Output Print the maximum number of friendly pairs.        Sample Input 1 3
2 0
3 1
1 3
4 2
0 4
5 5      Sample Output 1 2  For example, you can pair (2, 0) and (4, 2) , then (3, 1) and (5, 5) .       Sample Input 2 3
0 0
1 1
5 2
2 3
3 4
4 5      Sample Output 2 2  For example, you can pair (0, 0) and (2, 3) , then (1, 1) and (3, 4) .       Sample Input 3 2
2 2
3 3
0 0
1 1      Sample Output 3 0  It is possible that no pair can be formed.       Sample Input 4 5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7      Sample Output 4 5       Sample Input 5 5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9      Sample Output 5 4

Solution (Python):
def solve():
    n = int(input())
    a = []
    b = []
    c = []
    d = []
    for i in range(n):
        a_, b_ = map(int, input().split())
        a.append(a_)
        b.append(b_)

    for i in range(n):
        c_, d_ = map(int, input().split())
        c.append(c_)
        d.append(d_)

    import numpy as np
    a, b, c, d = np.array(a), np.array(b), np.array(c), np.array(d)

    arg = np.argsort(b)[::-1]
    a = a[arg]
    b = b[arg]

    argc = np.argsort(c)
    c = c[argc]
    d = d[argc]


    n_pair = 0
    for i in range(n):
        c_, d_ = c[i], d[i]
        for j, a_ in enumerate(a):
            b_ = b[j]
            if a_ < c_ and b_ < d_:
                n_pair += 1
                a = np.delete(a, j)
                b = np.delete(b, j)
                
                break

    print(n_pair)

solve()

Solution (Python):



N=int(input())
    
def dfs(u):
    for v in range(nv):
        if adj[u][v] and not visited[v]:
            visited[v] = True
            if matches[v] is None or dfs(matches[v]):
                matches[v] = u
                return True
    return False
 

nu=N
nv=N
adj = [[False] * nv for _ in range(nu)]
matches = [None] * nv
count = 0
 
a = []
b = []
for i in range(N):
    x1,y1=[int(i) for i in input().split()]
    a.append(x1)
    b.append(y1)
c = []
d = []
for i in range(N):
    x1,y1=[int(i) for i in input().split()]
    for j in range(N):
        if (x1-a[j])>0 and (y1-b[j])>0:
            adj[i][j] = True
 
for u in range(nu):
    visited = [False] * nv
    if dfs(u): count += 1
 
print(count)

Solution (Python):



import collections
import itertools
import sys



INF = 10 ** 8


REC_LIMIT = 10000


FlowEdge = collections.namedtuple("FlowEdge", "source sink capacity")


class FlowNetwork(object):

    """Class representing a flow network.

    :param int num_vertices: The number of vertices in the network.
    """

    def __init__(self, num_vertices):
        self.adj_edges = [set() for _ in range(num_vertices)]
        self.flow = None
        self.rev_edge = dict()
        self.used = None

    def get_edges_from(self, vertex):
        """Returns the set of edges adjacent to the vertex.

        :param int vertex: The index of vertex.
        :returns: The set of edges adjacent to the vertex.
        :rtype: set
        """

        return self.adj_edges[vertex]

    def add_edge(self, source, sink, capacity):
        """Add an edge u -> v to the flow network.

        :param int source: The vertex u.
        :param int sink: The vertex v.
        :param int capacity: The capacity of the edge.
        """

        assert source != sink
        forward_edge = FlowEdge(source, sink, capacity)
        backward_edge = FlowEdge(sink, source, 0)
        self.rev_edge[forward_edge] = backward_edge
        self.rev_edge[backward_edge] = forward_edge
        self.adj_edges[source].add(forward_edge)
        self.adj_edges[sink].add(backward_edge)

    def dfs(self, source, sink, flow):
        """Finding augmenting paths using depth-first search.

        This method is not supposed to be used directly.
        Instead, use :meth:`FlowNetwork.ford_fulkerson`.
        """

        if source == sink:
            return flow
        self.used[source] = True
        for edge in self.get_edges_from(source):
            rest = edge.capacity - self.flow[edge]
            if self.used[edge.sink] or rest <= 0:
                continue
            d = self.dfs(edge.sink, sink, min(flow, rest))
            if d > 0:
                self.flow[edge] += d
                self.flow[self.rev_edge[edge]] -= d
                return d
        return 0

    def ford_fulkerson(self, source, sink):
        """Computing maximum flow using the Ford-Fulkerson algorithm.

        :param int source: The source.
        :param int sink: The sink.
        :return: Maximum flow.
        """

        self.flow = collections.defaultdict(int)
        max_flow = 0
        while True:
            self.used = collections.defaultdict(bool)
            df = self.dfs(source, sink, INF)
            if df == 0:
                return max_flow
            else:
                max_flow += df


def compute_max_num_pairs(num_points, red_points, blue_points):
    network = FlowNetwork(2 + 2 * num_points)
    source_idx = 2 * num_points
    sink_idx = source_idx + 1
    
    
    for i in range(num_points):
        network.add_edge(source_idx, i, 1)
        network.add_edge(num_points + i, sink_idx, 1)
    g = itertools.product(enumerate(red_points),
                          enumerate(blue_points, start=num_points))
    for (ri, (rx, ry)), (bi, (bx, by)) in g:
        if rx < bx and ry < by:
            network.add_edge(ri, bi, 1)
    res = network.ford_fulkerson(source_idx, sink_idx)
    return res


def main():
    sys.setrecursionlimit(REC_LIMIT)
    num_points = int(input())
    red_points = [tuple(int(z) for z in input().split())
                  for _ in range(num_points)]
    blue_points = [tuple(int(z) for z in input().split())
                   for _ in range(num_points)]
    res = compute_max_num_pairs(num_points, red_points, blue_points)
    print(res)


if __name__ == '__main__':
    main()

Solution (Python):
def find(u, c, p, v):
    n = len(c)
    if not v[u]:
        v[u] = True
        for q in xrange(n):
            if c[u][q]:
                if p[q]==-1 or find(p[q], c, p ,v):
                    p[q] = u
                    return True
    return False

def maxMatch(c):
    foo = 0
    n = len(c)
    p = [-1 for i in xrange(n)]
    for i in xrange(n):
        v = [False for j in xrange(n)]
        if find(i, c, p, v):
            foo += 1
    return foo

def process(r, b):
    n = len(r)
    c = [[False for i in xrange(n)] for j in xrange(n)]
    for i in xrange(n):
        for j in xrange(n):
            if r[i][0]<b[j][0] and r[i][1]<b[j][1]:
                c[i][j] = True
    return maxMatch(c)

def main():
    n = int(raw_input().strip())
    r = []
    b = []
    for i in xrange(n):
        x, y = [int(sub) for sub in raw_input().strip().split()]
        r.append((x, y))
    for i in xrange(n):
        x, y = [int(sub) for sub in raw_input().strip().split()]
        b.append((x, y))
    print process(r, b)

if __name__=='__main__':
    main()

Solution (Python):
n = int(input())
a = []
for i in range(n):
    x, y = map(int, input().split())
    a.append((x, y))
b = []
for i in range(n):
    x, y = map(int, input().split())
    b.append((x, y))
sus = [[] for i in range(n)]
for i in range(n):
    for j in range(n):
        if a[i][0] < b[j][0] and a[i][1] < b[j][1]:
            sus[i].append(j)

conn = [-1 for i in range(n)]

def dfs(x):
    global bio
    bio[x] = 1
    for y in sus[x]:
        if conn[y] == -1:
            conn[y] = x
            return 1
        if bio[conn[y]] == 0 and dfs(conn[y]):
            conn[y] = x
            return 1
    return 0

s = 0
for i in range(n):
    bio = [0 for j in range(n)]
    s += dfs(i)
print(s)