P3385 负环

题目描述

给定一个 \(n\) 个点的有向图,请求出图中是否存在从顶点 \(1\) 出发能到达的负环。

负环的定义是:一条边权之和为负数的回路。

输入格式

本题单测试点有多组测试数据。

输入的第一行是一个整数 \(T\),表示测试数据的组数。对于每组数据的格式如下:

第一行有两个整数,分别表示图的点数 \(n\) 和接下来给出边信息的条数 \(m\)。

接下来 \(m\) 行,每行三个整数 \(u\),\(v\),\(w\)。

若 \(w \geqslant 0\),则表示存在一条从 \(u\) 至 \(v\) 边权为 \(w\) 的边,还存在一条从 \(v\) 至 \(u\) 边权为 \(w\) 的边。

若 \(w < 0\),则只表示存在一条从 \(u\) 至 \(v\) 边权为 \(w\) 的边。

输出格式

对于每组数据,输出一行一个字符串,若所求负环存在,则输出YES,否则输出NO

输入输出样例

输入 #1

  1. 2
  2. 3 4
  3. 1 2 2
  4. 1 3 4
  5. 2 3 1
  6. 3 1 -3
  7. 3 3
  8. 1 2 3
  9. 2 3 4
  10. 3 1 -8

输出 #1

  1. NO
  2. YES

数据规模

对于全部的测试点,保证:

  • \(
    1 \leqslant n \leqslant 2 \times 10^{3}, 1 \leqslant m \leqslant 3 \times 10^{3}
    \)

  • \(
    1 \leqslant u,v \leqslant n, 10^{-4} \leqslant w \leqslant 10^{-4}
    \)

  • \(
    1 \leqslant T \leqslant 10
    \)

题解

该题是一个判断给定图中是否存在负环(或负权回路)的模板题。

使用 \(Bellman-Ford\) 算法判负环。补充,\(SPFA\) 算法也可以判负环,但个人感觉没有该算法自然,而且两者时间复杂度相差不大,感兴趣的都可以实现一下,之后有时间会在此题补充图论中判负环的算法。

代码实现如下:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<iostream>
  5. #include<vector>
  6. #include<queue>
  7. #define PII pair<int, int>
  8. #define INF 0x3f3f3f3f
  9. using namespace std;
  10. struct edge
  11. {
  12. int u; // 边的起点
  13. int v; // 边的终点
  14. int w; // 边的权值
  15. };
  16. const int N = 2005; // 最大点数
  17. const int M = 3005; // 最大边数
  18. int n, m, q;
  19. vector<edge> es; // 用邻接表存储边
  20. int dist[N]; // 第i号点距离源点的当前最短距离
  21. int vis[N]; // vis数组存的是当前结点是否在队列中
  22. int releax(int e)
  23. {
  24. if (dist[es[e].u] == INF) {
  25. return 0;
  26. }
  27. else if (dist[es[e].u] + es[e].w < dist[es[e].v]) {
  28. dist[es[e].v] = dist[es[e].u] + es[e].w;
  29. return 1;
  30. }
  31. return 0;
  32. }
  33. bool bellman()
  34. {
  35. int sz = es.size();
  36. for (int i = 1; i <= n; ++i) {
  37. int flag = 1;
  38. for (int j = 0; j < sz; ++j) {
  39. if (releax(j)) {
  40. flag = 0;
  41. }
  42. }
  43. if (flag) return false;
  44. }
  45. for (int i = 0; i < sz; ++i) {
  46. if (releax(i)) return true;
  47. }
  48. return false;
  49. }
  50. int main()
  51. {
  52. int T;
  53. cin >> T;
  54. while (T--) {
  55. // 初始化
  56. es.clear();
  57. memset(dist, 0x3f, sizeof(dist));
  58. memset(vis, 0, sizeof(vis));
  59. cin >> n >> m;
  60. dist[1] = 0;
  61. vis[1] = 1;
  62. int u, v, w;
  63. for (int i = 0; i < m; ++i) {
  64. cin >> u >> v >> w;
  65. if (w >= 0) {
  66. edge tmpe1 = { u, v, w };
  67. edge tmpe2 = { v, u, w };
  68. es.push_back(tmpe1);
  69. es.push_back(tmpe2);
  70. }
  71. else {
  72. edge tmpe = { u, v, w };
  73. es.push_back(tmpe);
  74. }
  75. }
  76. if (bellman()) cout << "YES" << endl;
  77. else cout << "NO" << endl;
  78. }
  79. return 0;
  80. }

ACM - 图论 - P3385 负环的更多相关文章

  1. 【luogu P3385 负环】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3385 SPFA判负环. 这个题必须卡一卡才过得去. 按理说对于一个负环点应当是入队 > n次. 但是这 ...

  2. 洛谷P3385负环

    传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...

  3. 【洛谷 P3385】模板-负环(图论--spfa)

    题目:有一个图有N个顶点,M条边.边用三个整数a b w表示,意思为a->b有一条权值为w的边(若w<0则为单向,否则双向).共T组数据.对于每组数据,存在负环则输出一行"YE5 ...

  4. [P3385]【模板】负环 (spfa / bellman-ford)

    终于开始认真对待图论了 因为听说一直是提高组的,动得很少,直到现在机房打提高的氛围下,开始学一些皮毛的东西 模板题目链接 这是一道求负环的题目,照理来说大家都是用spfa来判断负环的 但是我觉得bel ...

  5. 「P3385」【模板】负环(spfa

    题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 ...

  6. 洛谷P3385判负环——spfa

    题目:https://www.luogu.org/problemnew/show/P3385 两种方法,dfs和bfs: 一开始写的dfs,要把dis数组初值赋成0,这样从一个连着负边的点开始搜: 在 ...

  7. 洛谷 P3385 【模板】负环

    P3385 [模板]负环 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M ...

  8. 洛谷 P3385 【模板】负环 题解

    P3385 [模板]负环 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环. 输入格式 第一行一个正整数T ...

  9. 模板+解题报告:luogu P3385 【模板】负环

    题目链接:P3385 [模板]负环 缩点板子. 看日报上说\(DFS\)会炸(我确实打炸了),就根据他的说明\(yy\)了\(BFS\),多一个记录步数的数组即可(我用的\(len[]\)),若\(l ...

随机推荐

  1. 使用 Postman 的 Environments 和 Tests 简化在不同环境中的切换步骤

    调试 API 的时候,我们需要经常需要在本地.开发.生产来回切换,还需要面临 Token 失效等的问题,让人头大,看到一些教程有介绍用 Postman 来简化流程,但是实践起来还是遇到一些问题,所以就 ...

  2. SQL Server 2005 - 让 SELECT 查詢結果额外增加递增序号

    /* 方法一*/SELECT 序號= (SELECT COUNT(客戶編號) FROM 客戶 AS LiMing                 WHERE LiMing.客戶編號<= Chan ...

  3. 由浅入深---MyBatis的全局配置文件

    从我开始接触代码,我就很怕写配置文件,一般的配置文件我都是直接从上一个项目复制到这个项目来改改,可能有部分同学也有我这种痛吧: 我目前一般的做法,先去找找例子(从网上,从github,从官网)之后再改 ...

  4. shell之局域网内脚本检查主机网络通讯(附并发改写)

    转至:https://blog.csdn.net/yrx420909/article/details/104355825 需求:写一个脚本,局域网内,把能ping通的IP和不能ping通的IP分类,并 ...

  5. (第三章)TF框架之实现验证码识别

    这里实现一个用神经网络(卷积神经网络也可以)实现验证码识别的小案例,主要记录本人做这个案例的流程,不会像之前那么详细,主要用作个人记录用... 这里是验证码的四个字母,被one-hot编码后形成的四个 ...

  6. Go基础知识梳理(一)

    Go基础知识梳理(一) Go中package的用法及作用 package hello 用于分包,Go通过包来管理命名空间 import ( "hello" //通过import关键 ...

  7. LeetCode-095-不同的二叉搜索树 II

    不同的二叉搜索树 II 题目描述:给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 .可以按 任意顺序 返回答案. 二叉搜索树(Binary ...

  8. salesforce零基础学习(一百一十二)项目中的零碎知识点小总结(四)

    本篇参考: https://trailblazer.salesforce.com/issues_view?id=a1p4V0000003znDQAQ https://salesforce.stacke ...

  9. 番茄钟的实现(基于Xilinx EGO1学习板)

    番茄钟设计 一.总体设计 1.番茄工作法简介 番茄工作法由意大利的奇列洛创造.其内容就是:工作25分钟休息5分钟,循环四次后休息15分钟. 本项目就是基于Xilinx Ego1开发板实现一个计时器,该 ...

  10. Windows 下 MySQL 简单定时自动备份、删除过期备份

    Windows 下 MySQL 简单定时自动备份.删除过期备份 MySQL Workbench 客户端虽然好用,但并不提供自动备份功能.手工备份,确实繁琐. 新建一个 数据库备份文件存放目录,本例为D ...