洛谷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判负环
[定义与概念] 给定一张有向图,若其中存在一个环的所有权值之和为负数,这个环称为负环. [算法实现] 当然,负环的求解可以暴搜,但是时间复杂度就难以入眼了,我们回到求解单源最短路径算法上面,看看它们能 ...
随机推荐
- mysql_config_editor使用简介
原文 : http://blog.itpub.net/29773961/viewspace-1817640/ ----------------------------------------- ...
- cocos2d-x调用android内嵌浏览器打开网页
cocos2d-x调用android内嵌浏览器打开网页,能够从入口传入网址,C++调用android 的api就可以实现. 方法也非常easy 1. 改动"cocos2dx\platform ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)(转)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- 【Java编程】Java在dos窗体编译与运行的批处理
近期在Java编程过程中,常常使用到dos窗体对程序进行编译与执行. 可是不方便之处在于每次都要输入命令进入将要编译的程序的文件夹(事实上也有简单的方法,在文章末尾给出).于是编写了一个配置文件,能够 ...
- hdu3251 最小割
题意: 给n个城市,m条有向边.每条边有权值,如今有些城市能够选择得到.可选的城市有一个价值.可是要满足从1到达不了这些城市,为了满足要求能够去掉一些边,须要花费边的权值,问终于得到的最大价值是多少, ...
- 系统安全-PAM
Pluggable Authentication Modules(可插入验证模块,简称PAM) Linux-PAM(Pluggable Authentication Modules for Linux ...
- qt-mingw530-opencv-开发配置
1.安装好Qt和Qtcreator 2.解压OpenCV源码到一个目录下.路径不能带空格和中文. 3.把E:\Qt\qtcreator-2.1.0\mingw\bin添加到系统环境变量中. 4.安装C ...
- 02 http协议之方法与状态码
一:HTTP请求信息和响应信息的格式 请求: ()请求行 ()请求头信息 ()请求主体信息(可以没有) () 头信息结束后和主体信息之间要空一行 请求行又分3部分 请求方法 请求路径 所用的协议 请求 ...
- ETL Automation完整安装方法_(元数据存放在mysql数据库)
安装前介质准备: DBI-1.636.tar.gz DBD-mysql-4.037.tar.gz ETL.tar mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz P ...
- return和exit的差别
#include<stdio.h> #include<sys/types.h> #include<sys/wait.h> #include<unistd.h& ...