POJ 3259 Wormholes 邻接表的SPFA判断负权回路
http://poj.org/problem?id=3259
题目大意:
一个农民有农场,上面有一些虫洞和路,走虫洞可以回到 T秒前,而路就和平常的一样啦,需要花费时间走过。问该农民可不可能从某个点出发后回到该点,并且于出发时间之前?
思路:
就是让我们判断存不存在一条总权值未负的回路。
你想想,如果我们一直走这个回路,就可以无限的回到过去。( (╯‵□′)╯︵┻━┻世上哪有时空隧道。想回到过去么?如果可以? 你会去做什么,挽回让自己后悔的事情? ,咳咳,继续题解。)
那就用SPFA呗,如果一个点入队次数超过n,那么就存在回路。(因为SPFA求最短路,如果存在环,那么会一直入队。。出。。,也就是说环的是没有最小值的,而正环只会走一次。)
SPFA常见的优化有SLF和LLL
SLF(Small Label First)是指在入队时如果当前点的dist值小于队首, 则插入到队首, 否则插入到队尾。
未优化的版本:
157MS
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
const int INF=9999999;
const int MAXN=520;
const int MAXM=5200;
struct edge
{
int to;
int val;
int next;
}e[MAXM];
int len,head[MAXN];
int dis[MAXN];
int n,m,w;
bool SPFA()
{
for(int i=1;i<=n;i++)
dis[i]=INF; bool vis[MAXN]={0};
int cnt[MAXN]={0}; int cur=1; queue<int> q;
q.push(cur);
vis[cur]=true;
cnt[cur]=1;
dis[cur]=0; while(!q.empty())
{
cur=q.front();
q.pop();
vis[cur]=false; for(int i=head[cur] ;i!=-1; i=e[i].next)
{
int id=e[i].to;
if( dis[cur] + e[i].val < dis[ id ] )
{
dis[ id ] = dis[cur] + e[ i ].val;
if(!vis[id])
{
cnt[id]++;
vis[id]=true;
q.push(id);
if(cnt[cur]>n)
return true;
}
}
}
}
return false;
} void add(int from,int to,int val)
{
e[len].to=to;
e[len].val=val;
e[len].next= head[from];
head[from]=len++;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(head,-1,sizeof(head));
len=0; scanf("%d%d%d",&n,&m,&w);
for(int i=0;i<m;i++)
{
int from,to,val;
scanf("%d%d%d",&from,&to,&val);
add(from,to,val);
add(to,from,val); //双向的
}
for(int i=0;i<w;i++)
{
int from,to,val;
scanf("%d%d%d",&from,&to,&val);
add(from,to,-val);
}
if( SPFA())
puts("YES");
else
puts("NO");
}
return 0;
}
采用优化的版本:
63MS
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
const int INF=9999999;
const int MAXN=520;
const int MAXM=5200;
struct edge
{
int to;
int val;
int next;
}e[MAXM];
int len,head[MAXN];
int dis[MAXN];
int n,m,w;
bool SPFA()
{
for(int i=1;i<=n;i++)
dis[i]=INF; bool vis[MAXN]={0};
int cnt[MAXN]={0}; int cur=1; deque<int> q;
q.push_back(cur);
vis[cur]=true;
cnt[cur]=1;
dis[cur]=0; while(!q.empty())
{
cur=q.front();
q.pop_front();
vis[cur]=false; for(int i=head[cur] ;i!=-1; i=e[i].next)
{
int id=e[i].to;
if( dis[cur] + e[i].val < dis[ id ] )
{
dis[ id ] = dis[cur] + e[ i ].val;
if(!vis[id])
{
cnt[id]++;
vis[id]=true;
if(cnt[cur]>n)
return true;
if(!q.empty() && dis[id] < dis[q.front()])
q.push_front(id);
else
q.push_back(id);
}
}
}
}
return false;
} void add(int from,int to,int val)
{
e[len].to=to;
e[len].val=val;
e[len].next= head[from];
head[from]=len++;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(head,-1,sizeof(head));
len=0; scanf("%d%d%d",&n,&m,&w);
for(int i=0;i<m;i++)
{
int from,to,val;
scanf("%d%d%d",&from,&to,&val);
add(from,to,val);
add(to,from,val); //双向的
}
for(int i=0;i<w;i++)
{
int from,to,val;
scanf("%d%d%d",&from,&to,&val);
add(from,to,-val);
}
if( SPFA())
puts("YES");
else
puts("NO");
}
return 0;
}
POJ 3259 Wormholes 邻接表的SPFA判断负权回路的更多相关文章
- POJ 3259 Wormholes【最短路/SPFA判断负环模板】
农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径 ...
- POJ 3259 Wormholes(最短路&spfa正权回路)题解
题意:给你m条路花费时间(双向正权路径),w个虫洞返回时间(单向负权路径),问你他能不能走一圈回到原点之后,时间倒流. 思路:题意有点难看懂,我们建完边之后找一下是否存在负权回路,存在则能,反之不能. ...
- POJ 3259 Wormholes(最短路,判断有没有负环回路)
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24249 Accepted: 8652 Descri ...
- Wormholes 虫洞 BZOJ 1715 spfa判断负环
John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地 ...
- POJ 3259 Wormholes ( SPFA判断负环 && 思维 )
题意 : 给出 N 个点,以及 M 条双向路,每一条路的权值代表你在这条路上到达终点需要那么时间,接下来给出 W 个虫洞,虫洞给出的形式为 A B C 代表能将你从 A 送到 B 点,并且回到 C 个 ...
- ACM: POJ 3259 Wormholes - SPFA负环判定
POJ 3259 Wormholes Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu ...
- POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)
题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts.我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前 ...
- poj 3259 Wormholes 判断负权值回路
Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...
- poj 3259 Wormholes
题目连接 http://poj.org/problem?id=3259 Wormholes Description While exploring his many farms, Farmer Joh ...
随机推荐
- 一题多解(三)—— Python 字符串的拼接
1. format def event_log(name, time): print('Event: {}, happens at {}'.format(name, str(time))) 2. 使用 ...
- vue methods 方法中 方法 调用 另一个方法。
vue在同一个组件内: methods中的一个方法调用methods中的另外一个方法. 可以在调用的时候 this.$options.methods.test(); this.$options.met ...
- 利用日志文件恢复MYSQL数据库
利用日志文件恢复MYSQL数据库 650) this.width=650;" onclick='window.open("http://blog.51cto.com/viewpic ...
- C/C++(语句,数组)
C语言语句: 两大选择,三大循环,四大跳转 两大跳转:if,switch 三大循环:for,while,do-while 四大跳转:break,continue,goto,return do-whil ...
- flask使用第三方云通讯平台时,出现{'172001':'网络错误'}解决方法
问题描述:flask使用第三方云通讯平台时,出现{'172001':'网络错误'} 解决方法: 在sms.py文件中添加如下代码 import ssl # 取消证书验证ssl._create_defa ...
- Myeclipse学习总结(2)——MyEclipse快捷键大全
1.ctrl+shift+R 打开资源 此组快捷键可以打开工程中任意一个文件,而本人只需按文件名或者mask名的字母顺序输入就会出现对应的文件或者在内容中某个关键字再按快捷键也可以的,例如:Custo ...
- Android中级第十讲--相机录像和查看系统相册图片
博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 录像比较简单,开始录制: myCamera.unlock(); ...
- 用openssl生成含有中文信息的证书
openssl 支持 ASCII 和 UTF-8 两种编码,应该可以制作中文证书. 在生成证书签发申请时,当输入中文则 openssl 报错,这是因为当前输入的字符是 ANSI 本地编码格式,超出了 ...
- Funui-overlay 如何添加theme 的 overlay
昨天更改theme主题的时候,发现所有仓库下的theme都是共用的.也就是说,如果你更改了52平台下的theme,那么你提交了代码以后,82下也会发生相应的更改.但是,昨天修改的theme属性,只在3 ...
- ::的类名前有个 & ,什么意思?
转载自 http://www.imooc.com/qadetail/93985 MazePerson &MazePerson::setPersonPosition(int coordinat ...