洛谷P3385判负环——spfa
题目:https://www.luogu.org/problemnew/show/P3385
两种方法,dfs和bfs;
一开始写的dfs,要把dis数组初值赋成0,这样从一个连着负边的点开始搜;
在一个负环上,一定会有一个点,从它开始绕环走,dis值一直为负,根据这个找环;
但是数据太强了,过不了:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=,MAXM=;
int T,n,m,head[MAXN],ct,dis[MAXN];
bool vis[MAXN],f;
struct N{
int to,next,w;
N(int t=,int n=,int w=):to(t),next(n),w(w) {}
}edge[MAXM];
void add(int x,int y,int z)
{
edge[++ct]=N(y,head[x],z);head[x]=ct;
}
int rd()
{
int x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
void dfs(int x)
{
if(f)return;
vis[x]=;
for(int i=head[x],u;i;i=edge[i].next)
{
u=edge[i].to;
if(f)return;
if(dis[u]>dis[x]+edge[i].w)
{
// printf("x=%d u=%d vis[u]=%d\n",x,u,vis[u]);
if(vis[u])
{
f=;return;
}
dis[u]=dis[x]+edge[i].w;
dfs(u);
if(f)return;
}
}
vis[x]=;//!
}
int main()
{
T=rd();
while(T--)
{
n=rd();m=rd();
ct=;f=;
memset(head,,sizeof head);
for(int i=,x,y,z;i<=m;i++)
{
x=rd();y=rd();z=rd();
add(x,y,z);
if(z>=)add(y,x,z);
}
memset(vis,,sizeof vis);
memset(dis,,sizeof dis);
for(int i=;i<=n;i++)
{
dfs(i);
if(f)break;
}
if(f)printf("YE5\n");
else printf("N0\n");
}
return ;
}
dfs
于是用bfs,根据最短路边数来判断,若边数>=n则有负环;
bfs的话还有一种判断方式,是根据被松弛次数,若>=n则有负环,但不如上面那个优;
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
//queue<int>q;
int const MAXN=,MAXM=,inf=;
int T,n,m,head[MAXN],ct,dis[MAXN],cnt[MAXN],que[MAXN],h,t;
bool vis[MAXN];
struct N{
int to,next,w;
N(int t=,int n=,int w=):to(t),next(n),w(w) {}
}edge[MAXM];
inline void add(int x,int y,int z){edge[++ct]=N(y,head[x],z);head[x]=ct;}
inline int rd()
{
int x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
inline bool spfa()
{
// while(q.size())q.pop();
memset(que,,sizeof que);h=;t=;
memset(dis,0x3f,sizeof dis);
memset(cnt,,sizeof cnt);
memset(vis,,sizeof vis);
// q.push(1);
vis[]=;dis[]=;que[t]=;
// while(q.size())
while(h!=t+)
{
// int x=q.top();vis[x]=0;q.pop();
int x=que[h++];vis[x]=;
if(h==inf)h=;
for(int i=head[x],u;i;i=edge[i].next)
if(dis[u=edge[i].to]>dis[x]+edge[i].w)
{
cnt[u]=cnt[x]+;
if(cnt[u]>=n)return ;
dis[u]=dis[x]+edge[i].w;
// if(!vis[u])vis[u]=1,q.push(u);
if(!vis[u])
{
vis[u]=;
t++;
if(t==inf)t=;
que[t]=u;
}
}
}
return ;
}
int main()
{
T=rd();
while(T--)
{
n=rd();m=rd();
ct=;
memset(head,,sizeof head);
for(int i=,x,y,z;i<=m;i++)
{
x=rd();y=rd();z=rd();
add(x,y,z);
if(z>=)add(y,x,z);
}
if(spfa())printf("YE5\n");
else printf("N0\n");
}
return ;
}
洛谷P3385判负环——spfa的更多相关文章
- 洛谷P3385 [模板]负环 [SPFA]
题目传送门 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个 ...
- 负环--spfa
洛谷板子题 负环?是有负权边的环还是一个边权之和为负的环? 还没有准确的定义(那就先忽略吧qwq 判断负环的方法: 暴力枚举/spfa/mellman—ford/奇怪的贪心/超神的搜索 可惜我只会sp ...
- 洛谷P3385 【模板】负环(DFS求环)
洛谷题目传送门 HNOI爆零前回刷模板题 非常不正经的题目,目前并没有合适的优秀算法,就算是大家公认的dfs(还是不要强行叫dfs-spfa吧,概念应该不一样,这就是暴力dfs松弛答案) 但是对于随机 ...
- 洛谷 P3385 【模板】负环 题解
P3385 [模板]负环 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环. 输入格式 第一行一个正整数T ...
- 洛谷—— P3385 【模板】负环
题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 ...
- 洛谷p3385【模板】负环
最近很久没怎么写最短路的题导致这个题交了好多遍 AC率是怎么下来的自己心里没点数 SPFA虽然臭名昭著但是他可以用来判负环 如果一个点进队的次数大于等于n说明存在负环 这道题一开始memset我给di ...
- 浅谈SPFA判负环
目录 SPFA判负环 [前言] [不可代替性] [具体实现] SPFA的过程 判负环 [核心代码] [例题] SPFA判负环 有不足的地方请指出 本蒟蒻一定会修改吼 [前言] 最短路的求法中最广为人知 ...
- BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...
- 【原创】SPFA判负环
[定义与概念] 给定一张有向图,若其中存在一个环的所有权值之和为负数,这个环称为负环. [算法实现] 当然,负环的求解可以暴搜,但是时间复杂度就难以入眼了,我们回到求解单源最短路径算法上面,看看它们能 ...
随机推荐
- react 路由传参
今天,我们要讨论的是react router中Link传值的三种表现形式.分别为通过通配符传参.query传参和state传参. ps:进入正题前,先说明一下,以下的所有内容都是在react-rout ...
- maximum-depth-of-binary-tree——找出数的最大深度
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- python(12)- 文件处理应用Ⅰ
一.读取文件,打印第三行时后面加入“徐亚平” 程序如下: count=0 with open("test",mode="r",encoding="ut ...
- vs2012 MinGW编译ffmpeg 出现libavdevice/avdevice.c(38) : error C2059: 语法错误:“.”
利用vs2012编译ffmpeg出现以下错误: libavdevice/avdevice.c(38) : error C2059: 语法错误:“.” libavdevice/avdevice.c(40 ...
- make mrproper及mrproper的含义
Linux下面去编译项目之前,一般常会用make mrproper去先删除之前编译所生成的文件和配置文件,备份文件等,其中,mrproper和distclean,clean之间的区别,Linux内核源 ...
- kubectl技巧之通过go-template截取属性
系列目录 在使用kubectl get获取资源信息的时候,可以通过-o(--output简写形式)指定信息输出的格式,如果指定的是yaml或者json输出的是资源的完整信息,实际工作中,输出内容过少则 ...
- Html调用 QQ接口
<A href="tencent://message/?uin=1805843351&Site=有事Q我&Menu=yes"> <img styl ...
- Time To First Byte (TTFB) 第一字节时间 页面加载时间
Time to first byte - Wikipedia https://en.wikipedia.org/wiki/Time_to_first_byte Time to first byte ( ...
- tornado之运行第一个tornado程序
Tornado是使用Python编写的一个强大的.可扩展的Web服务器.它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中. 首先是安装torn ...
- pexpect库学习之包装类详解
在pexpect库中,包装类的构造参数使用的命令或者要包装命令的提示符,还可以通过这个包装类来修改命令的提示符,那么所谓的包装类实际就是用于给用户交互相应的子命令,它的实例方法主要是“run_comm ...