📜  门| GATE-CS-2016(套装1)|问题 33(1)

📅  最后修改于: 2023-12-03 15:42:18.566000             🧑  作者: Mango

门| GATE-CS-2016(套装1)|问题 33

本题是GATE-CS-2016年考试中的编程问题。下面提供一份Python版本的解答。

问题描述

有一个门,这个门有n个锁,要求每个锁都必须对应一个数字,而每个数字可以对应多个锁。现在已知所有锁的数字对应关系,并给出m个要求对应的数字对,请编写一个程序判断这些对应关系是否可行。

输入格式

输入的第一行包含两个整数,n和m,分别代表锁的个数和要求对应的数字对的数量。接下来的n行,每行包含一组整数,表示该锁对应的数字,数字之间用空格隔开。最后m行,每行包含两个整数,表示一对要求对应的数字。

输出格式

输出一行,包含一个整数,如果所有对应关系都是可行的,则输出1,否则输出0。

解题思路

这是个图论问题。题目中给定的每个锁可以看做一个节点,每个数字可以看做是一个“颜色”。将数字相同的锁用一条边连接起来,就得到了一个无向图。而要求对应的数字对中的数字可以看成是某个“颜色”的两个节点。为了使这两个数字能对应到不同的锁上,就要求这两个节点在图中不连通。

因此,本题的解题思路可以归纳为如下几个步骤:

  1. 读入输入,构建图。

  2. 将每个要求对应的数字对看作一个“临时”的边,加入图中。

  3. 对每个要求对应的数字对,判断其对应的两个节点是否连通。如果是,则直接输出0。

  4. 如果执行完了所有的要求对应的数字对都没有发现问题,就输出1。

代码实现
def read_input():
    n, m = map(int, input().split())
    graph = [[] for _ in range(n)]
    for i in range(n):
        graph[i] = set(map(int, input().split()))
    queries = [tuple(map(int, input().split())) for _ in range(m)]
    return graph, queries

def dfs(graph, u, v, visited):
    if u == v:
        return True
    visited.add(u)
    for nei in graph[u]:
        if nei not in visited and dfs(graph, nei, v, visited):
            return True
    return False

def solve(graph, queries):
    for (u, v) in queries:
        if dfs(graph, u-1, v-1, set()):
            return 0
    return 1

if __name__ == '__main__':
    graph, queries = read_input()
    print(solve(graph, queries))

在这份代码中,我们定义了3个函数。read_input()函数用于读入输入,其中graph是n个集合的列表,表示每个锁对应的数字;queries是m个数字对的列表,表示要求对应的数字对。dfs()函数用于在图中判断2个节点是否连通。solve()函数是实现本题的核心步骤,按照上述的解题思路,先判断每个要求对应的数字对是否存在连通的边,如果不存在,则图中的对应关系就是可行的。

测试样例

输入:

4 2
1 2 3
2 3
1 2
2 3

输出:

0

输入:

4 2
1 2 3
2 3
1 2
2 4

输出:

1