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,百度内 ...
随机推荐
- Nyoj 修路方案(次小生成树)
描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在,军师小工已经找到 ...
- 网页上弹出pop窗口实例,(document).height()与$(window).height()的区别
#dvbg{background-color:#666666; position:absolute; z-index:99; left:0; top:0; display:none; width:10 ...
- crawler_google工作原理
- uva 12003 Array Transformer (大规模阵列)
白皮书393页面. 乱搞了原始数组中.其实用另一种阵列块记录. 你不能改变原始数组. 请注意,与原来的阵列和阵列块的良好关系,稍微细心处理边境.这是不难. #include <cstdio> ...
- Hibernate_10_继承的例子_单表
只是建一个表,所有属性都包括在此表.使用discriminator 到父和子类之间的区别. 1)父类(Article): public class Article { private Integer ...
- Cocos2D-X2.2.3学习笔记3(内存管理)
本章节介绍例如以下: 1.C/C++内存管理机制 2.引用计数机制 3.自己主动释放机制 1.C/C++内存管理机制 相信仅仅要懂oop的都知道NEW这个keyword吧,这个通俗点说事实上就是创建对 ...
- windows下exfat无法写入修复
为了可以实现mac与windows文件共享,把移动硬盘格式化为exfat了,但是在osx中放入文件后,在windows上紧进行读取写入时出现错误,提示使用chkdsk进行修正,以下是修正步骤. ①wi ...
- 在Installshield的安装进度中显示自己设置的信息
原文:在Installshield的安装进度中显示自己设置的信息 以Installscript msi project为例,在installshield所制作的安装包安装过程中显示安装进度的,就在On ...
- MvcPager分页控件以适用Bootstrap
随笔- 9 文章- 0 评论- 33 修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载) 软件开发分页效果必不可少,对于Asp.Net MVC 而言,MvcPag ...
- jQuery EasyUI API - Base - Draggable [原创汉化官方API]
最近在学习jQuery EasyUI,发现中文的文档好少,部分文档不错但它是鸟语的,为了大家也为了自己学习吧,汉化做一下笔记. 有没有说清楚的,或者翻译不正确的地方还请大家谅解指出.. 由于工作时间原 ...