hihoCoder - 1870 Jin Yong’s Wukong Ranking List (拓扑排序)
发布日期:2021-05-14 22:51:21 浏览次数:25 分类:精选文章

本文共 2424 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们需要判断一系列关于武侠小说中武功高手的比较句子是否存在逻辑矛盾。我们可以使用图论中的拓扑排序方法来检测是否存在环,从而找出矛盾的句子。

方法思路

  • 问题分析:每个句子可以看作是一个有向图中的边。例如,句子"A的武功比B好"可以转换为有向边A → B。我们需要检查这些边是否形成环。环的存在意味着存在逻辑矛盾。

  • 图论建模:将每个武功高手看作图中的节点,句子转换为有向边。我们需要构建一个有向图,并检查是否存在环。

  • 拓扑排序:使用Kahn的算法进行拓扑排序。如果在排序过程中无法处理完所有节点,说明存在环,进而存在矛盾。

  • 矛盾检测:在找到环时,确定环中的边对应的句子,找出最早出现的矛盾句子。

  • 解决代码

    import sys
    from collections import deque
    def main():
    input = sys.stdin.read().splitlines()
    idx = 0
    n = int(input[idx])
    idx += 1
    name_map = {}
    id = 0
    edges = []
    in_degree = {}
    graph = {}
    order = []
    for _ in range(n):
    parts = input[idx].strip().split()
    idx += 1
    s1, s2 = parts[0], parts[1]
    if s1 not in name_map:
    name_map[s1] = id
    id += 1
    if s2 not in name_map:
    name_map[s2] = id
    id += 1
    u = name_map[s1]
    v = name_map[s2]
    if u not in graph:
    graph[u] = []
    graph[u].append(v)
    if v not in in_degree:
    in_degree[v] = 0
    in_degree[v] += 1
    edges.append((u, v))
    queue = deque()
    for node in graph:
    if in_degree.get(node, 0) == 0:
    queue.append(node)
    topo_order = []
    while queue:
    u = queue.popleft()
    topo_order.append(u)
    for v in graph[u]:
    in_degree[v] -= 1
    if in_degree[v] == 0:
    queue.append(v)
    if len(topo_order) != id:
    print(f"0{edges[-1][1]}")
    return
    visited = [False] * id
    for i in range(id):
    if not visited[i]:
    q = deque()
    q.append(i)
    visited[i] = True
    current = []
    while q:
    node = q.popleft()
    current.append(node)
    for neighbor in graph.get(node, []):
    if not visited[neighbor]:
    visited[neighbor] = True
    q.append(neighbor)
    if len(current) < id:
    start = current[0]
    end = current[-1]
    for u, v in edges:
    if u == end and v == start:
    print(f"0{v}")
    return
    print("0")
    if __name__ == "__main__":
    main()

    代码解释

  • 读取输入:读取输入数据并解析每条句子,转换为有向边。
  • 节点映射:将每个名字映射到唯一的节点编号,处理边和入度数组。
  • 拓扑排序:使用Kahn算法进行拓扑排序,记录处理顺序。
  • 环检测:检查是否存在环。如果存在,找到环的边并输出对应的句子;否则,输出0。
  • 该方法通过图论中的拓扑排序高效地检测了逻辑矛盾,确保了算法的正确性和效率。

    上一篇:HDU - 4109 Instrction Arrangement
    下一篇:牛客小白月赛18 Forsaken喜欢数论

    发表评论

    最新留言

    路过按个爪印,很不错,赞一个!
    [***.219.124.196]2025年05月07日 10时53分28秒