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,百度内 ...
随机推荐
- 改动ubuntu/linux文件夹显示颜色
通过secureCRT登陆linux,假设背景颜色选为黑色,非常可能在使用ls命令时看不清楚文件夹名,这时候我们能够通过一个简单的方式将文件夹变为一个显眼的颜色,比如"黄色". [ ...
- Android - JNI加入标准C++文件
JNI加入标准C++文件 本文地址: http://blog.csdn.net/caroline_wendy 其余參考: http://blog.csdn.net/caroline_wendy/art ...
- hust1384---The value of F[n]
Description For any integer i>=3 we have F[i]=(F[i-1]+2*F[i-2]+3*F[i-3])%9901; Now give you F[0], ...
- sql server、c# 命名规范
查了不少资料,没有我想要的. 还不如下载 官方的 数据 Northwind ,pubs 参见 https://www.microsoft.com/en-us/download/confirmation ...
- 转载:善待Redis中的数据
Redis是我们数据的保管者,我们可以随时存随时取,大的小的,重要的不重要的,它都毫无怨言的帮我们保存着,甚至有些时候,我们变得很懒,存东西进去的时候顺便还贴张纸:"过了一个星期就帮我扔了吧 ...
- Ajax.ActionLink 用法
Ajax.ActionLink 用法 Ajax 属性的ActionLink方法可以创建一个具有异步行为的锚标签. ActionLink方法的第一个参数指定了链接文本,第二个参数是要异步调用的操作的名称 ...
- Spring IOC之 使用JSR 330标准注解
从Spring 3.0开始,Spring提供了对 JSR 330标准注解的支持.这些注解可以喝Spring注解一样被扫描到.你只需要将相关的Jar包加入到你的classpath中即可. 注意:如果你使 ...
- 设计与实现的简单和经常使用的权限系统(五岁以下儿童):不维护节点的深度level,手工计算level,树形结构
以这种方式.和第三的类似介绍.所不同的是.深度未在数据库中存储节点level,添加和更改时间,护.而是,在程序中,实时去计算的. 至于后面的,依照level升序排序,再迭代全部的节点构造树,与第三篇 ...
- 1cocos2dx扩展UI控制,CCControlSlider,CCScale9Sprite(九妹图。),CCControlSwitch,CCControlButton
UI控件来自cocos2dx的扩展库.完好了UI方面的元素,使cocos2dx更加丰富多彩.使用扩展库需包括: #include "cocos-ext.h" USING_NS ...
- js获取当前指定的前几天的日期(如当前时间的前七天的日期)
这里就不多说了,直接贴上代码: <html> <head> <meta http-equiv="Content-Type" content=" ...