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判断负权回路的更多相关文章

  1. POJ 3259 Wormholes【最短路/SPFA判断负环模板】

    农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径 ...

  2. POJ 3259 Wormholes(最短路&spfa正权回路)题解

    题意:给你m条路花费时间(双向正权路径),w个虫洞返回时间(单向负权路径),问你他能不能走一圈回到原点之后,时间倒流. 思路:题意有点难看懂,我们建完边之后找一下是否存在负权回路,存在则能,反之不能. ...

  3. POJ 3259 Wormholes(最短路,判断有没有负环回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24249   Accepted: 8652 Descri ...

  4. Wormholes 虫洞 BZOJ 1715 spfa判断负环

    John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地 ...

  5. POJ 3259 Wormholes ( SPFA判断负环 && 思维 )

    题意 : 给出 N 个点,以及 M 条双向路,每一条路的权值代表你在这条路上到达终点需要那么时间,接下来给出 W 个虫洞,虫洞给出的形式为 A B C 代表能将你从 A 送到 B 点,并且回到 C 个 ...

  6. ACM: POJ 3259 Wormholes - SPFA负环判定

     POJ 3259 Wormholes Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu   ...

  7. POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)

    题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts.我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前 ...

  8. poj 3259 Wormholes 判断负权值回路

    Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u   Java ...

  9. poj 3259 Wormholes

    题目连接 http://poj.org/problem?id=3259 Wormholes Description While exploring his many farms, Farmer Joh ...

随机推荐

  1. Outlook中设置会议的提醒

    https://support.office.com/en-us/article/Set-or-remove-reminders-7a992377-ca93-4ddd-a711-851ef359792 ...

  2. VS中创建自定义一个VC工程为基础的开发向导的总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 VS允许用户进行自定义开发向导.自定义开发向导的好处在于将常用的设置都通过向导生成,从而大大提供开发效率.特别是在开发 ...

  3. JavaScript--数据结构与算法之链表实现约瑟夫环

    传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第三个人时将 ...

  4. JS面向对象系列教程 — 对象的基本操作

    面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object),意思就是事物,在面向对象的思维中,它将一 ...

  5. 最简单的基于FFmpeg的移动端例子:Android 视频转码器

    http://blog.csdn.net/leixiaohua1020/article/details/47056365

  6. 国内搜索大哥iOS面试题

    每一次面试之后都会对问到的面试题进行总结. 这篇总结的是我面试某大型搜索公司的iOS面试题.一面(15min)+二面(30min).并拿到实习offer.当然在今天这个特殊的节日,祝大家新年快乐.希望 ...

  7. Oracle11gR2 Windows 7 64bit and PL/SQL Developer排错

    1.Environment variable: "PATH" - This test checks whether the length of the environment va ...

  8. Leetcode47: Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. 推断一个链表是不是回文的,一个比較简单的办法是把链表每一个结点的值存在vect ...

  9. lightSlider 好图片轮播插件 支持移动端

    http://jquery-plugins.net/jquery-lightslider-lightweight-responsive-content-slider https://github.co ...

  10. vim学习3

    可视模式: