博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Usaco2006 Dec]Wormholes
阅读量:5775 次
发布时间:2019-06-18

本文共 2029 字,大约阅读时间需要 6 分钟。

题目描述

John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N(从1..N标号)块地,并有W个虫洞。其中1<=N<=500,1<=M<=2500,1<=W<=200。现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。

输入格式

Line 1: 一个整数 F, 表示农场个数。

Line 1 of each farm: 三个整数 N, M, W。

Lines 2..M+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地,中间有一条用时T秒的小路。

Lines M+2..M+W+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地,中间有一条可以使John到达T秒前的虫洞。

输出格式

Lines 1..F: 如果John能在这个农场实现他的目标,输出"YES",否则输出"NO"


由于题中所说,M条无向边已经连接了N个点,所以所有虫洞都必定属于至少一个简单环。

所以这题只需要判一下负环即可,这里我们可以用到SPFA。我们不停地将节点松弛,直到某个节点被松弛了超过n次,就说明有负环。

这种方法比较低效,这里介绍一种更高效的。记cnt[u]表示u到起点经过多少个点。那么每次松弛:if(dis[v]>dis[u]+edge(u,v)) then dis[v]=dis[u]+edge(u,v)时,我们令cnt[v]=cnt[u]+1。显然,起点到终点的最短路不会超过n-1个节点(起点不算)。那么我们松弛时一旦发现cnt[v]=n-1就说明有负环。

时间复杂度都是O(KM),但第二种明显更高效:第一种要将v入队n次才能判负环,而第二种只需要((n-1)/环的节点数)次即可。

#include
#include
#include
#include
#define maxn 100001#define maxm 100001#define maxw 201using namespace std; struct edge{ int to,dis,next; edge(){} edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }}e[maxm*2+maxw];int head[maxn],k; int dis[maxn],cnt[maxn];bool inq[maxn];int n,m,w; inline int read(){ register int x(0),f(1); register char c(getchar()); while(c<'0'||'9'
q; q.push(1),inq[1]=true,dis[1]=0; while(q.size()){ int u=q.front(); q.pop(),inq[u]=false; for(register int i=head[u];~i;i=e[i].next){ int v=e[i].to; if(dis[v]>dis[u]+e[i].dis){ dis[v]=dis[u]+e[i].dis,cnt[v]=cnt[u]+1; if(cnt[v]>=n) return true; if(!inq[v]) q.push(v),inq[v]=true; } } } return false;} int main(){ int t=read(); while(t--){ memset(head,-1,sizeof head); n=read(),m=read(),w=read(); for(register int i=1;i<=m;i++){ int u=read(),v=read(),w=read(); add(u,v,w),add(v,u,w); } for(register int i=1;i<=w;i++){ int u=read(),v=read(),w=read(); add(u,v,-w); } printf("%s\n",spfa()?"YES":"NO"); } return 0;}

*数据与题目描述不符,建议数组开大点。

转载于:https://www.cnblogs.com/akura/p/10976077.html

你可能感兴趣的文章
java入门第二季--封装--什么是java中的封装
查看>>
【人物志】美团前端通道主席洪磊:一位产品出身、爱焊电路板的工程师
查看>>
一份关于数据科学家应该具备的技能清单
查看>>
机器学习实战_一个完整的程序(一)
查看>>
Web框架的常用架构模式(JavaScript语言)
查看>>
如何用UPA优化性能?先读懂这份报告!
查看>>
这些Java面试题必须会-----鲁迅
查看>>
Linux 常用命令
查看>>
NodeJS 工程师必备的 8 个工具
查看>>
CSS盒模型
查看>>
ng2路由延时加载模块
查看>>
使用GitHub的十个最佳实践
查看>>
全面了解大数据“三驾马车”的开源实现
查看>>
脱离“体验”和“安全”谈盈利的游戏运营 都是耍流氓
查看>>
慎用!BLEU评价NLP文本输出质量存在严重问题
查看>>
基于干净语言和好奇心的敏捷指导
查看>>
Node.js 2017企业用户调查结果发布
查看>>
“软”苹果水逆的一周:杂志服务崩溃,新机型遭泄露,芯片首架离职
查看>>
JAVA的优势就是劣势啊!
查看>>
ELK实战之logstash部署及基本语法
查看>>