题目描述

暴力枚举/\(SPFA\)/\(Bellman-ford\)/奇怪的贪心/超神搜索

寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环。

输入输出格式

输入格式

第一行一个正整数\(T\)表示数据组数,对于每组数据:

第一行两个正整数\(N\) \(M\),表示图有\(N\)个顶点,\(M\)条边

接下来\(M\)行,每行三个整数\(a\) \(b\) \(w\),表示\(a->b\)有一条权值为\(w\)的边(若\(w<0\)则为单向,否则双向)

输出格式

共\(T\)行。对于每组数据,存在负环则输出一行\("YE5"\)(不含引号),否则输出一行\("N0"\)(不含引号)。

输入输出样例

输入样例#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

N0
YE5

说明

\[n\leq 2000
\]

\[m\leq 3000
\]

\[-10000\leq w\leq 10000
\]

\[T\leq 10
\]

建议复制输出格式中的字符串。

本题数据感谢\(@negiizhao\)的精心构造,请不要使用玄学算法

本题数据有更新

题解

由题意得:负环就是一个边权之和为负的环。

由于\(Dijkstra\)算法不能求解带有负权边的图,因此我们就使用\(SPFA\)算法求解。(题目不是说了吗)

接下来,就是套用\(SPFA\)算法模板的时间了!

如何判定负环呢?

根据负环的定义,我们可以设\(cnt[x]\)表示从\(1\)到\(x\)的最短路径包含的边数,初始化\(cnt[1]=0\)。

当执行\(dis[y] = dis[x] + z\)时,\(cnt[y] = cnt[x] + 1\)。

若此时发现\(cnt[y] ≥n\),就说明图中有负环。

若算法正常结束,就说明图中没有负环。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <queue> using namespace std; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
} int ver[10005], nxt[10005], head[10005], e[10005], tot;
int n, m, ans, vis[10005], dis[10005], cnt[10005];
int u = 1; inline void add(int u, int v, int w)
{
ver[++tot] = v, e[tot] = w, nxt[tot] = head[u], head[u] = tot;
}//邻接表存图 inline bool SPFA()
{
queue <int> q;
memset(dis, 0x3f3f3f3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
vis[u] = 1, dis[u] = 0, cnt[u] = 1;
q.push(u);
while (!q.empty())
{
int x = q.front(); q.pop();
vis[x] = 0;
for (int i = head[x]; i; i = nxt[i])
{
int y = ver[i], z = e[i];
if (dis[y] > dis[x] + z)
{
dis[y] = dis[x] + z;
cnt[y] = cnt[x] + 1;
if (cnt[y] > n) return true;//有负环
if (!vis[y])
{
vis[y] = 1; q.push(y);
}
}
}
}
return false;
}
//以上为SPFA算法 int main()
{
int t = gi();
while (t--)
{
tot = 0;
memset(cnt, 0, sizeof(cnt));
memset(head, 0, sizeof(head));//多测要清空
n = gi(), m = gi();
for (int i = 1; i <= m; i++)
{
int x = gi(), y = gi(), z = gi();
add(x, y, z);
if (z >= 0)//是双向边
{
add(y, x, z);
}
}
if (SPFA()) puts("YE5");//图中有负环
else puts("N0");//没有负环
}
return 0;
}

题解【洛谷P3385】【模板】负环的更多相关文章

  1. 洛谷P3385 [模板]负环 [SPFA]

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

  2. 洛谷P3385判负环——spfa

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

  3. <题解>洛谷P3385 【模板】负环

    题目链接 判断一张图中是否存在关于顶点1的负环: 可以用SPFA跑一遍,存在负环的情况就是点进队大于n次 因为在存在负环的情况下,SPFA会越跑越小,跑进死循环 在最差的情况下,存在的负环长度是“n+ ...

  4. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

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

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

  6. 洛谷P3385 【模板】负环(DFS求环)

    洛谷题目传送门 HNOI爆零前回刷模板题 非常不正经的题目,目前并没有合适的优秀算法,就算是大家公认的dfs(还是不要强行叫dfs-spfa吧,概念应该不一样,这就是暴力dfs松弛答案) 但是对于随机 ...

  7. 洛谷 P3385 【模板】负环

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

  8. 洛谷—— P3385 【模板】负环

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

  9. 洛谷 P3385 【模板】负环 (SPFA)

    题意:有一个\(n\)个点的有向图,从\(1\)出发,问是否有负环. 题解:我们可以用SPFA来进行判断,在更新边的时候,同时更新路径的边数,因为假如有负环的话,SPFA这个过程一定会无限重复的遍历这 ...

随机推荐

  1. Wannafly Camp 2020 Day 2E 阔力梯的树 - set,启发式合并

    搞一波启发式合并即可 #include <bits/stdc++.h> using namespace std; #define int long long #define iter se ...

  2. 如何架构一个 React 项目?

    编程有点像搞园艺.比起竭力去对付BUG(虫子),我们更愿意把一切弄得整洁有序,以免最后落得个身在荒野丛林中.低劣的架构会拖我们的后腿,也会使得BUG更容易钻进系统里去. 想要对你的项目进行架构,方法有 ...

  3. bat文件一键运行python自动化脚本

    目标:建立一个双击即可运行自动化脚本的机制,而不用每次运行编译器,方便测试人员用户体验. 方法: 1. 将所有代码打包成exe文件,但一旦修改,又要重新打包. 2. 将运行代码写成bat文件,双击即执 ...

  4. Token:服务端身份验证的流行方案

    01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服 ...

  5. 打开UML类图的正确姿势

    UML(Unified Modeling Language) 统一建模语言,又称标准建模语言.是用来对软件密集系统进行可视化建模的一种语言.UML的定义包括UML语义和UML表示法两个元素.UML是在 ...

  6. OpenCV3.0 + VS2015出现“ACCESS_MASK不明确”错误

    问题:Vs 使用openCV 3.0+ 出错error C2872: “ACCESS_MASK”: 不明确的符号 环境: 系统:Win7 环境:VS2015 64bit 原因: 是因为我项目中的其中一 ...

  7. dmesg用法

    百科概念:dmesg是一种程序,用于检测和控制内核环缓冲.程序用来帮助用户了解系统的启动信息. 解释:dmesg命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件 ...

  8. 自定义jstl标签*

    原文链接:https://www.it610.com/article/442039.htm 步骤如下: 1.写tld文档:用来指定标签的名字,标签库等. 2.写标签处理器类. 3.配置到web.xml ...

  9. TWF

    design seq1_b3 sta_label 0.0-1.0 0.0-1.0 1e-9 # clocks# clockID clock_name period rise_edge fall_edg ...

  10. guava的简单使用

    引入依赖 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId ...