79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
|
class GFG:
|
||
|
def __init__(self,graph):
|
||
|
|
||
|
# residual graph
|
||
|
self.graph = graph
|
||
|
self.ppl = len(graph)
|
||
|
self.jobs = len(graph[0])
|
||
|
|
||
|
# A DFS based recursive function
|
||
|
# that returns true if a matching
|
||
|
# for vertex u is possible
|
||
|
def bpm(self, u, matchR, seen):
|
||
|
|
||
|
# Try every job one by one
|
||
|
for v in range(self.jobs):
|
||
|
|
||
|
# If applicant u is interested
|
||
|
# in job v and v is not seen
|
||
|
if self.graph[u][v] and seen[v] == False:
|
||
|
|
||
|
# Mark v as visited
|
||
|
seen[v] = True
|
||
|
|
||
|
'''If job 'v' is not assigned to
|
||
|
an applicant OR previously assigned
|
||
|
applicant for job v (which is matchR[v])
|
||
|
has an alternate job available.
|
||
|
Since v is marked as visited in the
|
||
|
above line, matchR[v] in the following
|
||
|
recursive call will not get job 'v' again'''
|
||
|
if matchR[v] == -1 or self.bpm(matchR[v],
|
||
|
matchR, seen):
|
||
|
matchR[v] = u
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
# Returns maximum number of matching
|
||
|
def maxBPM(self):
|
||
|
'''An array to keep track of the
|
||
|
applicants assigned to jobs.
|
||
|
The value of matchR[i] is the
|
||
|
applicant number assigned to job i,
|
||
|
the value -1 indicates nobody is assigned.'''
|
||
|
matchR = [-1] * self.jobs
|
||
|
|
||
|
# Count of jobs assigned to applicants
|
||
|
result = 0
|
||
|
for i in range(self.ppl):
|
||
|
|
||
|
# Mark all jobs as not seen for next applicant.
|
||
|
seen = [False] * self.jobs
|
||
|
|
||
|
# Find if the applicant 'u' can get a job
|
||
|
if self.bpm(i, matchR, seen):
|
||
|
result += 1
|
||
|
return result
|
||
|
|
||
|
|
||
|
def main():
|
||
|
n, m = map(int, input().split())
|
||
|
friendships = [list(map(int, input().split())) for _ in range(m)]
|
||
|
|
||
|
graph = []
|
||
|
for i in range(n):
|
||
|
line = [0]*(2*n)
|
||
|
graph.append(line)
|
||
|
|
||
|
for a, b in friendships:
|
||
|
graph[a-1][n+b-1] = 1
|
||
|
|
||
|
for i in range(n):
|
||
|
line = [0]*(2*n)
|
||
|
graph.append(line)
|
||
|
|
||
|
print(GFG(graph).maxBPM())
|
||
|
|
||
|
|
||
|
for _ in range(int(input())):
|
||
|
main()
|