vijos1053 用spfa判断是否存在负环
MARK 用spfa判断是否存在负环
判断是否存在负环的方法有很多,
其中用spfa判断的方法是:如果存在一个点入栈两次,那么就存在负环。
细节想想确实是这样,按理来说是不存在入栈两次的如果边权值为正的话
这个算法是O(N*M)
还有一种方法是直接用bellman-ford,虽说spfa也就是bellman-ford+FIFO队列
而且bellman-ford还可以计算负环的值
顺手附上代码好了:
for(int i=0;i<n;i++) d[i]=INF;//初始化
d[0]=0; for(int k=0;k<n-1;k++)//迭代n-1次,目前不懂为什么
for(int i=0;i<m;i++){//检查每条边
int x=u[i],y=v[i];
if(d[x]<INF) d[y]<?=d[x]+w[i];
}
这一题我是没有用bellman-ford...因为看到有人说用这个超时了= =
这里说一下用spfa的做法= =
虽然本蒟蒻第6个点莫名WA,但是毕竟思路还是正确的,自己MARK一下
目测是一些地方没有考虑到吧,据说有重边?有可能是这个?= =懒得管了
其实就是每个点都spfa一遍,看是否存在负环;
如果不存在的的话,就输出s-这些点的距离
至于spfa里面,其实也很简单,就是
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(dist[v]>dist[u]+e[i].w){
dist[v]=dist[u]+e[i].w;
if(!vis[v]){
vis[v]=true;
q.push(v);
if(ans[v]<2){//这里用数组ans记录下,v这个点入栈几次
ans[v]++;
}
else return true;
}
}
}
}
附上完整代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const int maxn=101000;
int n,m,k,t,x,y,s,z,tot=0;
struct edge{
int from,to,w,next;
}e[1010000];
int head[maxn],dist[maxn],ans[maxn];
bool vis[maxn];
int f[maxn];
bool flag;
void add(int x,int y,int z){
e[tot].from=x;
e[tot].to=y;
e[tot].w=z;
e[tot].next=head[x];
head[x]=tot++;
}
bool spfa(int s){
queue<int>q;
memset(dist,63,sizeof(dist));
memset(vis,false,sizeof(vis));
memset(ans,0,sizeof(ans));
q.push(s);
dist[s]=0;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(dist[v]>dist[u]+e[i].w){
dist[v]=dist[u]+e[i].w;
if(!vis[v]){
vis[v]=true;
q.push(v);
if(ans[v]<2){
ans[v]++;
}
else return true;
}
}
}
}
return false;
}
int main(){
freopen("data.txt","r",stdin);
scanf("%d%d%d",&n,&m,&s);
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
if(x==y && z<0){
printf("-1\n");
return 0;
}
}
for(int i=1;i<=n;i++){
if(spfa(i)){
printf("-1\n");
return 0;
}
}
spfa(s);
for(int i=1;i<=n;i++){
if(dist[i]>1000000){
if(i!=s) printf("NoPath\n");
else printf("0\n");
}
else printf("%d\n",dist[i]);
}
return 0;
}
vijos1053 用spfa判断是否存在负环的更多相关文章
- poj3259 Wormholes【Bellman-Ford或 SPFA判断是否有负环 】
题目链接:poj3259 Wormholes 题意:虫洞问题,有n个点,m条边为双向,还有w个虫洞(虫洞为单向,并且通过时间为倒流,即为负数),问你从任意某点走,能否穿越到之前. 贴个SPFA代码: ...
- POJ 3259 Wormholes(最短路,判断有没有负环回路)
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24249 Accepted: 8652 Descri ...
- POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)
题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts.我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前 ...
- uva558 Wormholes SPFA 求是否存在负环
J - Wormholes Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Stat ...
- poj3259Wormholes (Bellman_Ford/SPFA/Floyed算法判断是否存在负环)
题目链接:http://poj.org/problem?id=3259 题目大意:一个图,有n个顶点,其中有m条边是双向的且权值为为正,w条边是单向的且权值为负,判断途中是否存在负环,如果有输出YES ...
- 使用spfa算法判断有没有负环
如果存在最短路径的边数大于等于点数,就有负环 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你判断图中是否存在负权回路. 输入格式 第一行包含整数n和m. 接下来m行每行 ...
- POJ 1151 Wormholes spfa+反向建边+负环判断+链式前向星
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 49962 Accepted: 18421 Descr ...
- bellman-ford算法(判断有没有负环)
#include <iostream> #include <vector> #include<string> #include<cstring> usi ...
- spfa算法及判负环详解
spfa (Shortest Path Faster Algorithm) 是一种单源最短路径的算法,基于Bellman-Ford算法上由队列优化实现. 什么是Bellman_Ford,百度内 ...
随机推荐
- CSS设置滚动条样式[转]
原文转载地址:http://www.javascript100.com/?p=756 webkit浏览器css设置滚动条 主要有下面7个属性 ::-webkit-scrollbar 滚动条整体部分,可 ...
- 第13章 模版方法模式(Template Method)
原文 第13章 模版方法模式(Template Method) 模板模式 模板模式 举例:模拟下数据库的update方法,先删除在插入. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- PHP memcache实现消息队列实例
现在,memcache于server缓存广泛应用.下面我来介绍一下memcache消息队列中等待的样本实现,有需要了解的朋友可以参考. memche消息队列原则key上做文章.后消息或者日志. 然后通 ...
- 有趣iOS开展 - 网络请求
网络请求 $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split(' ...
- oracle_利用闪回功能恢复数据
方便起见一般:执行如下即可不用往下看: ① 启用行移动功能 alter table tbl_a enable row movement; ② 闪回表数据到某个时间点 flashback table t ...
- 开源 java CMS - FreeCMS2.3员
原文地址:http://javaz.cn/site/javaz/site_study/info/2015/28375.html 项目地址:http://www.freeteam.cn/ 会员注冊 打 ...
- SQL表连接
背景 在上次的自考科目<数据库系统原理>中.已经接触到了关于数据库表连接的一些知识,近期的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回想一下. 导图总结 首先用一张思维导图 ...
- jQuery整理您的笔记----jQuery开始
Jquery它是一种高速.简明的JavaScript相框,jQuery设计目标:Write Less,Do More(写更少的代码,做很多其他的事情). 一.Jquery框架优势: 1.轻量级 jQu ...
- IplImage 封装释放
IplImage是openCV库中非常重要的一个结构体,库中的图像都是保存为这个结构体后再进行操作的,详细结构例如以下: </pre><pre> typedef struct ...
- 一步一步写算法(之n!中末尾零的个数统计)
原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...