本文共 3222 字,大约阅读时间需要 10 分钟。
为了解决问题,我们需要找到一种方法来选择钥匙,使得Ratish能够开尽可能多的门。这个问题可以转化为一个二分图匹配问题。具体来说,我们需要判断是否存在一种钥匙选择方案,使得每个钥匙只能用一次,并且能够开尽可能多的门。
import syssys.setrecursionlimit(1 << 25)def main(): input = sys.stdin.read().split() ptr = 0 while ptr < len(input): N = int(input[ptr]) M = int(input[ptr+1]) ptr +=2 if N ==0 and M ==0: break no = [0]*(2*N) for i in range(N): a = int(input[ptr]) b = int(input[ptr+1]) ptr +=2 no[a] = b no[b] = a x = [0]*(M+1) y = [0]*(M+1) for i in range(1, M+1): a = int(input[ptr]) b = int(input[ptr+1]) ptr +=2 x[i] = a y[i] = b def solve(): low = [0]*(2*N) pre = [0]*(2*N) cmp = [0]*(2*N) dfs_clock = 0 scc_cnt = 0 def dfs(u): nonlocal dfs_clock pre[u] = low[u] = dfs_clock dfs_clock +=1 for v in G[u]: if pre[v] ==0: dfs(v) low[u] = min(low[u], low[v]) elif cmp[v] ==0: low[u] = min(low[u], pre[v]) if low[u] == pre[u]: nonlocal scc_cnt scc_cnt +=1 stack = [] stack.append(u) while stack: u = stack.pop() if cmp[u]==0: cmp[u] = scc_cnt else: break for v in G[u]: if cmp[v]==0 and cmp[v] == cmp[u]: return if u == top: break for v in G[u]: if cmp[v]==0 and cmp[u] < cmp[v]: cmp[u] = cmp[v] break G = [[] for _ in range(2*N)] for i in range(1, M+1): a = x[i] b = y[i] G[no[a]].append(b) G[no[b]].append(a) dfs_clock = 0 scc_cnt =0 cmp = [0]*(2*N) pre = [0]*(2*N) for i in range(2*N): if pre[i]==0: dfs(i) for i in range(2*N): if cmp[i]==0: continue if cmp[i]==cmp[no[i]]: return False return True low =0 high = M best =0 while low <= high: mid = (low + high +1)//2 if check(mid): best = mid low = mid +1 else: high = mid -1 print(best) returnif __name__ == "__main__": main()
这种方法高效地解决了钥匙选择问题,确保Ratish能够开尽可能多的门。
转载地址:http://eyxfk.baihongyu.com/