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 ...
随机推荐
- Objective-C_类的扩展
一Category的定义和使用 二Extension的定义和使用 三Protocol的定义和使用 delegate的使用 一.Category的定义和使用 Category,分类或类目.主要作用是为没 ...
- android 图片特效处理之 图片叠加
这篇将讲到图片特效处理的图片叠加效果.跟前面一样是对像素点进行处理,可参照前面的android图像处理系列之七--图片涂鸦,水印-图片叠加和android图像处理系列之六--给图片添加边框(下)-图片 ...
- 怎样通过MSG_WAITALL设置阻塞时间,IO模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL
首先给出MSDN上一段设置阻塞超时的代码:(网址为http://social.msdn.microsoft.com/Forums/zh-SG/visualcpluszhchs/thread/3d9da ...
- 56.如何清除已经设置的npm config配置
npm config delete registry npm config delete disturl 或者 npm config edit 找到淘宝那两行,删除
- POJ 3174 暴力枚举
思路: 暴力枚举三个点 判一判 搞定 (x1*y1=x2*y2) x1.y1.x2.y2为他们两两的差 //By SiriusRen #include <cstdio> using nam ...
- 在Red Hat Linux服务器端假设NSF Server来进行Linux系统安装全过程
本教程讲述了通过在Red Hat Linux服务器端假设NSF Server来进行Linux系统安装的过程,并详细介绍了如何制作网络启动盘的细节.演示直观,讲解通俗易懂,特别适合初学者 ...
- Fragment-生命周期
Fragment生命周期图 一.Fragment的几种状态: 与Activity类似,Fragment也有一下几种状态: · 活动状态:当前Fragment位于前台,可见,可获得焦点. · 暂停状态: ...
- channels
package main import ( "fmt" "time" "strconv") func pinger(c chan strin ...
- mount 命令
命令格式:mount [-t vfstype] [-o options] device dir 嵌入式设备挂载命令mount -o nolock -t nfs 192.168.1.24:/home/t ...
- ACTIVATE STANDBY
ACTIVATE STANDBY 在有些场景下我们需要激活standby为primary,使用激活的standby完成一些的需求. 如: - 拿激活后的standby做应用测试. - primary宕 ...