SPFA - Luogu 3385 【模板】负环
【模板】负环
描述
找负环
输入
第一行一个正整数T表示数据组数,对于每组数据:
第一行两个正整数N M,表示图有N个顶点,M条边
接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)
输出
共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。
样例
输入
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
输出
N0
YE5
提示
N,M,|w|≤200 000;1≤a,b≤N;T≤10 建议复制输出格式中的字符串。
此题普通Bellman-Ford或BFS-SPFA会TLE
此题普通Bellman-Ford或BFS-SPFA真的会TLE!证明: https://www.luogu.org/record/show?rid=3554669
判断负环最常用的就是spfa。当然各位大佬搜索暴力也能过的……
而判负环的spfa也有2种,一种是BFS,而另一种是DFS。怎么都是大法师
BFS
BFS的尤其简单
在普通的spfa上加一个数组,记录各个点被更新/入栈的次数,一旦大于了某个数(一般取点数)就判定是有负环的。
BFS_SPFA的期望时间复杂度是\(O(\)边数\(*\)所有顶点进队的平均次数\()\),
既然存在负环,这个期望的时间复杂度就真的是期望了,鬼知道这负环有多长,还要绕多少圈,慢的一比。
DFS
而DFS的要改一改
找负环,就是找一条权值和为负的回路,
而在我们的DFS过程中,根据SPFA,我们找到的负环一定包含当前枚举的这个点。
即相当于我们找了一圈回来,发现现在的权值比原来的要小,那么我们就一定走了一个负环。
那么我们就分别枚举所有的点作为起点找负环,为了不TLE,如果已经找到一个负环就不再继续枚举。
代码蒯上
#include<iostream>
#include<iomanip>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 200002;
struct edge{int to,ne,len;edge(){to=ne=len=0;}}e[_<<1];
int he[_]={0},ecnt=0;
void add(int fr,int to,int len)
{e[++ecnt].to=to,e[ecnt].len=len,e[ecnt].ne=he[fr],he[fr]=ecnt;}
int n,m,dis[_];
bool ed[_]={0},vict;
void spfa(int d)
{
register int i,b;
if(vict)return;
ed[d]=1;
for(i=he[d];i;i=e[i].ne)
{
b=e[i].to;
if(dis[d]+e[i].len<dis[b])
{dis[b]=dis[d]+e[i].len;if(ed[b]){vict=1;return;}spfa(b);}
}
ed[d]=0;
return;
}
int main()
{
register int i,k,a,b,t=gotcha();
while(t--)
{
n=gotcha(),m=gotcha();
memset(he,0,4*n+8),memset(ed,0,n+2),memset(dis,63,4*n+8),ecnt=0,vict=0;
for(i=1;i<=m;i++)
{
a=gotcha(),b=gotcha(),k=gotcha();
add(a,b,k);if(k>=0)add(b,a,k);
}
for(i=1;i<=n;i++){spfa(i);if(vict)break;}
if(vict)puts("YE5");
else puts("N0");
}
return 0;
}
SPFA - Luogu 3385 【模板】负环的更多相关文章
- vijos1053 用spfa判断是否存在负环
MARK 用spfa判断是否存在负环 判断是否存在负环的方法有很多, 其中用spfa判断的方法是:如果存在一个点入栈两次,那么就存在负环. 细节想想确实是这样,按理来说是不存在入栈两次的如果边权值为正 ...
- uva558 Wormholes SPFA 求是否存在负环
J - Wormholes Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Stat ...
- LG P2285 [模板]负环(spfa判负环)
题目描述 寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环. 输入格式 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 接下来M行,每 ...
- 【洛谷 P3385】模板-负环(图论--spfa)
题目:有一个图有N个顶点,M条边.边用三个整数a b w表示,意思为a->b有一条权值为w的边(若w<0则为单向,否则双向).共T组数据.对于每组数据,存在负环则输出一行"YE5 ...
- 洛谷P3385 [模板]负环 [SPFA]
题目传送门 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个 ...
- SPFA算法的判负环问题(BFS与DFS实现)
经过笔者的多次实践(失败),在此温馨提示:用SPFA判负环时一定要特别小心! 首先SPFA有BFS和DFS两种实现方式,两者的判负环方式也是不同的. BFS是用一个num数组,num[x] ...
- 【洛谷P3385】模板-负环
这道题普通的bfs spfa或者ballen ford会T 所以我们使用dfs spfa 原因在于,bfs sfpa中每个节点的入队次数不定,退出操作不及时,而dfs则不会 既然,我们需要找负环,那么 ...
- POJ 1151 Wormholes spfa+反向建边+负环判断+链式前向星
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 49962 Accepted: 18421 Descr ...
- poj 3259 Wormholes 【SPFA&&推断负环】
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36852 Accepted: 13502 Descr ...
随机推荐
- logname,who -m,who -q,id,su,su -l 用户名,su -,date,cal,cal 12 2009,cal -y 2008,du -s 目录,
logname,who -m,who -q,id,su,su -l 用户名,su -,date,cal,cal 12 2009,cal -y 2008,du -s 目录,
- Neo4j-3.0.3 (Debian 8)
平台: Ubuntu 类型: 虚拟机镜像 软件包: neo4j-3.0.3 basic software database graph database infrastructure neo4j op ...
- redis在Windows下以后台服务一键搭建集群(多机器)
redis在Windows下以后台服务一键搭建集群(多机器) 一.概述 此教程介绍如何在windows系统中多台机器之间布置redis集群,同时要以后台服务的模式运行.布置以脚本的形式,一键完成.多台 ...
- CentOs7 修复 引导启动
一.修复MBR: MBR(Master Boot Record主引导记录): 硬盘的0柱面.0磁头.1扇区称为主引导扇区.其中446Byte是bootloader,64Byte为Partition t ...
- IOS 控制器View的创建方式(方式的优先级 、view的延迟加载)
MJViewController的view的创建 的方式的优先级 控制器view的延迟加载 ● 控制器的view是延迟加载的:用到时再加载 ● 可以用isViewLoaded方法判断一个UIViewC ...
- UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
最长回文子序列可以用求解原串s和反转串rv的LCS来得到,因为要求回文串分奇偶,dp[i][j]保存长度, 要求字典序最小,dp[i][j]应该表示回文子序列的端点,所以边界为单个字符,即i+j=le ...
- 【BZOJ2733】[HNOI2012] 永无乡(启发式合并Splay)
点此看题面 大致题意: 给你一张图,其中每个点有一个权值,有两种操作:在两点之间连一条边,询问一个点所在联通块第\(k\)小的权值. 平衡树 看到第\(k\)小,应该不难想到平衡树. 为了练习\(Sp ...
- 【BZOJ1057】[ZJOI2007] 棋盘制作(单调栈的运用)
点此看题面 大致题意: 给你一个\(N*M\)的\(01\)矩阵,要求你分别求出最大的\(01\)相间的正方形和矩形(矩形也可以是正方形),并输出其面积. 题解 这题第一眼看去没什么思路,仔细想想,能 ...
- 【BZOJ1433】[ZJOI2009] 假期的宿舍(二分图匹配入门)
点此看题面 大致题意:有\(n\)个学生,其中一部分是在校学生,一部分不是,而在校学生中一部分回家,一部分不回家,并且我们用一个01矩阵表示学生之间相互认识关系.已知每个学生只能睡自己认识的人的床(当 ...
- 2018.5.21 . XMLSpy激活的方法
127.0.0.1 altova.com #XMLspy 127.0.0.1 www.altova.com #XMLspy 127.0.0.1 link.altova.com #XMLspy 追加加到 ...