洛谷P3385判负环——spfa

时间:2023-02-21 18:10:17

题目: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的更多相关文章

  1. 洛谷P3385 &lbrack;模板&rsqb;负环 &lbrack;SPFA&rsqb;

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

  2. 负环--spfa

    洛谷板子题 负环?是有负权边的环还是一个边权之和为负的环? 还没有准确的定义(那就先忽略吧qwq 判断负环的方法: 暴力枚举/spfa/mellman—ford/奇怪的贪心/超神的搜索 可惜我只会sp ...

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

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

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

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

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

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

  6. 洛谷p3385【模板】负环

    最近很久没怎么写最短路的题导致这个题交了好多遍 AC率是怎么下来的自己心里没点数 SPFA虽然臭名昭著但是他可以用来判负环 如果一个点进队的次数大于等于n说明存在负环 这道题一开始memset我给di ...

  7. 浅谈SPFA判负环

    目录 SPFA判负环 [前言] [不可代替性] [具体实现] SPFA的过程 判负环 [核心代码] [例题] SPFA判负环 有不足的地方请指出 本蒟蒻一定会修改吼 [前言] 最短路的求法中最广为人知 ...

  8. BZOJ&period;4500&period;矩阵&lpar;差分约束 SPFA判负环 &sol; 带权并查集&rpar;

    BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...

  9. 【原创】SPFA判负环

    [定义与概念] 给定一张有向图,若其中存在一个环的所有权值之和为负数,这个环称为负环. [算法实现] 当然,负环的求解可以暴搜,但是时间复杂度就难以入眼了,我们回到求解单源最短路径算法上面,看看它们能 ...

随机推荐

  1. 更改SharePoint 2007&sol;2010&sol;2013 Web 应用程序端口号

    之前创建的Web应用程序端口为80,因为其他需要要将端口更改为85,下面是具体步骤: 第一步:更改IIS绑定. 打开IIS服务管理器,右击需要更改的站点,选择编辑绑定. 在打开的网站绑定窗口,选择端口 ...

  2. osx开发,skport项目记录

    最近在研究前端框架,学习了一下vue.js,而后找到了element.js,后来又了解到了cooking···前端开发真是三天小更新,一周大变样,一个月天翻地覆啊··· 期间在使用cooking时遇到 ...

  3. Wine install&comma; 卸载的方法

    EL6 (RHEL6 and SL6) Required packages for proper building of 32-bit Wine on 64-bit EL6 yum install - ...

  4. &lpar;转&rpar;使用DataTime这个类来获取当前的时间

    我们可以通过使用DataTime这个类来获取当前的时间.通过调用类中的各种方法我们可以获取不同的时间:如:日期(--).时间(::).日期+时间(-- ::)等. //获取日期+时间 DateTime ...

  5. APP常用模块

    2016年上半年 APICloud合作云服务商提供了各种类型模块多达45个 其中最新发布的重要模块有 美洽客服模块 亲加视频直播相关模块 保利威视视频播放器模块 苹果银联支付模块 贝宝支付模块 谷歌分 ...

  6. Openjudge-计算概论(A)-求出e的值

    描述: 利用公式e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! 求e .输入输入只有一行,该行包含一个整数n(2<=n<=15),表示计算e时累加到1/n! ...

  7. 一步一步教你如何用Python做词云

    前言 在大数据时代,你竟然会在网上看到的词云,例如这样的. 看到之后你是什么感觉?想不想自己做一个? 如果你的答案是正确的,那就不要拖延了,现在我们就开始,做一个词云分析图,Python是一个当下很流 ...

  8. 使用sort函数进行排序

    介绍 C++的一个重要组成部分STL(Standard Template Library),即标准模板库,是一些高级数据结构和算法的集合:高级数据结构(容器)主要包括list.set.vector.m ...

  9. post请求参数设置

    控制器参数有[FromBody]修饰参数这么传: 控制器没有[FromBody]修饰参数这么传:

  10. php-- orther

    0.PHP实现物流查询(通过快递网API实现) 1.php7 新特性 2.php的精确计算 3.PHP大小写是否敏感问题的汇总 4.取得类的 对象属性名 和类的属性 和类的方法名 5.php判断 != ...