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. 关于TabLayout+ViewPager组合实现多页面滑动

    转载请注明出处:http://blog.csdn.net/ht_android/article/details/46647711 在android提供的design library中新增了一个控件,叫 ...

  2. EF搭建数据库

    http://blog.csdn.net/mss359681091/article/details/52135867http://blog.csdn.net/x_craft/article/detai ...

  3. 使用Java语言开发微信公众平台(三)

            在上一节课程中,我们来学习了微信公众平台最基础的一个接口——access_token,并且能够从微信公众平台中取到access_token. 那么,在本节课程中,我们要以上节课获取到的 ...

  4. BZOJ5332: [Sdoi2018]旧试题(莫比乌斯反演)

    时光匆匆,转眼间又是一年寒暑…… 这是小 Q 同学第二次参加省队选拔赛. 今年,小 Q 痛定思痛,不再冒险偷取试题,而是通过练习旧 试题提升个人实力.可是旧试题太多了,小 Q 没日没夜地做题,却看不到 ...

  5. 【MongoDB】mongodump and mongorestore of mogodb

    The another tool will be mentioned in this blog, namely mongodump and mongorestore. General speaking ...

  6. Android记录16-友盟第三方登录、分享实现

    Android开发记录16-友盟第三方登录.分享实现 2014年博客之星,投票地址username=wwj_748#content" style="font-family: Kai ...

  7. Elasticsearch中JAVA API的使用

    1.Elasticsearch中Java API的简介 Elasticsearch 的Java API 提供了非常便捷的方法来索引和查询数据等. 通过添加jar包,不需要编写HTTP层的代码就可以开始 ...

  8. BZOJ 1027 JSOI2007 合金 计算几何+Floyd

    题目大意:给定一些合金,选择最少的合金,使这些合金能够按比例合成要求的合金 首先这题的想法特别奇异 看这题干怎么会想到计算几何 并且计算几何又怎么会跟Floyd挂边 好强大 首先因为a+b+c=1 所 ...

  9. VBA调试利器debug.print

    作者:iamlaosong 百度一下.非常easy找到debug.print解释和使用介绍.事实上非常简单.就是将代码运行结果显示在"马上窗体"中,但不影响程序运行.VBA程序调试 ...

  10. BZOJ2157: 旅游(LCT)

    Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间 ...