ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

904 虫洞(spfa找负环)

2021-11-03 22:59:27  阅读:161  来源: 互联网

标签:count 904 int 路径 next 负环 vis spfa dis


1. 问题描述:

农夫约翰在巡视他的众多农场时,发现了很多令人惊叹的虫洞。虫洞非常奇特,它可以看作是一条 单向 路径,通过它可以使你回到过去的某个时刻(相对于你进入虫洞之前)。农夫约翰的每个农场中包含 N 片田地,M 条路径(双向)以及 W 个虫洞。现在农夫约翰希望能够从农场中的某片田地出发,经过一些路径和虫洞回到过去,并在他的出发时刻之前赶到他的出发地。他希望能够看到出发之前的自己。请你判断一下约翰能否做到这一点。翰拥有的农场数量 F,以及每个农场的完整信息。已知走过任何一条路径所花费的时间都不超过 10000 秒,任何虫洞将他带回的时间都不会超过 10000 秒。

输入格式

第一行包含整数 F,表示约翰共有 F 个农场。对于每个农场,第一行包含三个整数 N,M,W。接下来 M 行,每行包含三个整数 S,E,T,表示田地 S 和 E 之间存在一条路径,经过这条路径所花的时间为 T。再接下来 W 行,每行包含三个整数 S,E,T,表示存在一条从田地 S 走到田地 E 的虫洞,走过这条虫洞,可以回到 T 秒之间。

输出格式

输出共 F 行,每行输出一个结果。如果约翰能够在出发时刻之前回到出发地,则输出 YES,否则输出 NO。

数据范围

1 ≤ F ≤ 5
1 ≤ N ≤ 500,
1 ≤ M ≤ 2500,
1 ≤ W ≤ 200,
1 ≤ T ≤ 10000,
1 ≤ S,E ≤ N

输入样例:

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

输出样例:

NO
YES
来源:https://www.acwing.com/problem/content/description/906/

2. 思路分析:

3. 代码如下:

import collections
from typing import List


class Solution:
    def spfa(self, n: int, g: List[List[int]]):
        q = collections.deque()
        vis = [0] * (n + 1)
        # count记录到某个点的最短路径的边数
        count = [0] * (n + 1)
        # dis初始化为任意值都可以, 因为存在负环所以到某个点的最短路径长度一定大于等于n
        dis = [0] * (n + 1)
        for i in range(1, n + 1):
            # 将所有点入队
            q.append(i)
            vis[i] = 1
        while q:
            t = q.popleft()
            vis[t] = 0
            for next in g[t]:
                if dis[next[0]] > dis[t] + next[1]:
                    dis[next[0]] = dis[t] + next[1]
                    count[next[0]] = count[t] + 1
                    if count[next[0]] >= n: return True
                    if vis[next[0]] == 0:
                        q.append(next[0])
                        vis[next[0]] = 1
        return False

    def process(self):
        # T组测试数据
        T = int(input())
        while T > 0:
            n, m1, m2 = map(int, input().split())
            g = [list() for i in range(n + 1)]
            for i in range(m1):
                # 这里m1是无向边
                a, b, c = map(int, input().split())
                g[a].append((b, c))
                g[b].append((a, c))
            # 虫洞属于负数边
            for i in range(m2):
                a, b, c = map(int, input().split())
                g[a].append((b, -c))
            # 存在负环
            if self.spfa(n, g):
                print("YES")
            else:
                print("NO")
            T -= 1


if __name__ == "__main__":
    Solution().process()

标签:count,904,int,路径,next,负环,vis,spfa,dis
来源: https://blog.csdn.net/qq_39445165/article/details/121132632

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有