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

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

输出 #1

NO
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\) 算法也可以判负环,但个人感觉没有该算法自然,而且两者时间复杂度相差不大,感兴趣的都可以实现一下,之后有时间会在此题补充图论中判负环的算法。

代码实现如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#define PII pair<int, int>
#define INF 0x3f3f3f3f
using namespace std; struct edge
{
int u; // 边的起点
int v; // 边的终点
int w; // 边的权值
}; const int N = 2005; // 最大点数
const int M = 3005; // 最大边数
int n, m, q;
vector<edge> es; // 用邻接表存储边
int dist[N]; // 第i号点距离源点的当前最短距离
int vis[N]; // vis数组存的是当前结点是否在队列中 int releax(int e)
{
if (dist[es[e].u] == INF) {
return 0;
}
else if (dist[es[e].u] + es[e].w < dist[es[e].v]) {
dist[es[e].v] = dist[es[e].u] + es[e].w;
return 1;
}
return 0;
} bool bellman()
{
int sz = es.size();
for (int i = 1; i <= n; ++i) {
int flag = 1;
for (int j = 0; j < sz; ++j) {
if (releax(j)) {
flag = 0;
}
}
if (flag) return false;
}
for (int i = 0; i < sz; ++i) {
if (releax(i)) return true;
}
return false;
} int main()
{
int T;
cin >> T;
while (T--) {
// 初始化
es.clear();
memset(dist, 0x3f, sizeof(dist));
memset(vis, 0, sizeof(vis));
cin >> n >> m;
dist[1] = 0;
vis[1] = 1;
int u, v, w;
for (int i = 0; i < m; ++i) {
cin >> u >> v >> w;
if (w >= 0) {
edge tmpe1 = { u, v, w };
edge tmpe2 = { v, u, w };
es.push_back(tmpe1);
es.push_back(tmpe2);
}
else {
edge tmpe = { u, v, w };
es.push_back(tmpe);
}
}
if (bellman()) cout << "YES" << endl;
else cout << "NO" << endl;
} return 0;
}

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. pycharm创建模板

    用pycharm构造作者模板 模板,就是创建一个文件时自动生成模板内容. 这里用pycharm创建作者模板,步骤如下: File-->Settings Editor-->File and ...

  2. 案例一:shell脚本指定日期减去一天

    如果只减去一天的话,直接写就可以了. #date -d"yesterday 20150401" +%Y%m%d 如果要减去几天,还可以这样写,如果用负数是往前数, #date -d ...

  3. 【windows安全性 之访问控制】 访问控制 详细解说

    windows的安全性的两个基本支柱是身份验证(登入)和授权(访问控制). 身份验证是标识用户的过程 ,授权在验证了所标识用户是否可以访问特定资源之后进行. 相关的命名空间和类: System.Sec ...

  4. c# $ @特殊字符

    c# @ 停止字符串中的转义字符,让字符串内的转义字符当正常字符输入. 因此,如果你需要类似"所见所得"效果的赋值,逐字字符串赋值方式会是你的首选!此外,需要注意的是,当使用符号 ...

  5. AHUACM寒假集训VI(网络流)

    luoguP2472.蜥蜴 传送门 题目大意: R × C ( 1 ≤ R , C ≤ 20 ) R\times C(1\leq R,C\leq20) R×C(1≤R,C≤20)的网格上,每个格子有一 ...

  6. WPS二级标题链接到一级标题

    WPS二级标题链接到一级标题,即2后出现2.1 2.2而不是1.3 1.4什么的 样式中的编号什么的都不用动,默认即可,关键在于这些多级标题是否选择了同一个编号方式 WPS中,只需要将它们的编号选择为 ...

  7. net core or Linux

    某用户执行net core sdk 版本不生效 sudo chmod +x /home/username/netcore3.1sdk/dotnet //某个用户执行新版本net core sdk

  8. c++刷leetcode记录

    #include<iostream> #include<sstream> #include<vector> std::vector<int> split ...

  9. 测试平台系列(91) 编写oss管理页面

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们编写好了oss相关 ...

  10. SpringBoot接入轻量级分布式日志框架(GrayLog)

    我是3y,一年CRUD经验用十年的markdown程序员‍常年被誉为优质八股文选手 前两天我不是发了一篇数据链路追踪的文章嘛,在末尾也遗留了TODO:运行应用的服务器一般是集群,日志数据会记录到不同的 ...