SGU103 单源最短路问题

10 篇文章 0 订阅
【题目描述】
  在dingilville城中交通由一些道路构成。每个节点由一些道路连接而成。两个不同的节点之间最多拥有一条路,没有一条路连向自己,所需时间与路的长度相同。每一个点都有一个信号灯,在任何时刻它是蓝色或者紫色, 每一种颜色是周期变化的:蓝色持续一段时间然后紫色持续一段时间。允许你沿着一路从一个点到另一个点,此时必须满足着两个点的 信号灯的颜色在这一段时间内相同。今有一张城市地图它包括下列信息:
1.每一条路的长度即所需时间(整数)
2.每个节点信号灯两种颜色持续的时间(整数)
3.每个点信号灯最初的颜色和它持续的时间
你的任务是找到一条路试的从源点到汇点的旅行时间最短。
它包括哪些路你必须需要走的。
【输入格式】
第一行两个整数 源点和汇点的标号
第二行两个整数 总共有n个节点 m条边
下接n行 每行是一个节点的信息,共四个整数
 c r tB tP
c表示该节点最初的颜色
r表示最初颜色持续的时间
tB 蓝色持续的时间
tP 紫色持续的时间
下接m行 每行为一条边的信息,共三个整数
i j lij——始边 终边 长度
【输出格式】
若存在路径
第一行包括从源点到汇点的最短路
第二行包含从源到汇的最短路径
若不存在路径
一个整数0
【样例】
input
1 4
4 5
B 2 16 99
P 6 32 13
P 2 87 4
P 38 96 49
1 2 4
1 3 40
2 3 75
2 4 76
3 4 77


【数据范围】
n<=300
m<=14000
lig<100

r<t

【问题分析】

  简而言之,就是一张随着时间变化连通性的地图,求解单源最短路。我们可以考虑SPFA、dijkstra两种常见的单源最短路算法。最重要的是判断两点在某一时刻是否可以走,如果不可以则求得最小等待时间,如果永远不可以走:即这两盏灯在任意时刻灯的颜色都不同,或者可以换而言之,初相位相异,周期不同。不过事实上有如下代码【表示个人代码风格十分奇葩】

int wait(int x,int y)//考虑x y两个点需要等待的时间
{
  int now,tmp;//当前时间
  int cx,cy,rx,ry,nx,ny;
  /*
    简述我的逗比时间函数
	首先求出当前时间两个灯的颜色
	然后运行一个周期找到两个灯颜色相同的时候 
  */ 
  /*
   c- B 0
      P 1
      当前x点灯的颜色  cx 此时已经经过该颜色的时间为 rx 
	  下一个变动的时刻 now+p[x].time[cx]-rx 此时的颜色为1-cx 
	  
	  当前y点灯的颜色  cy 此时已经经过该颜色的时间为ry
	  下一个变动的时刻 now+p[y].time[cx]-ry 此时的颜色为1-cy 
	   
	   呵呵简直就是在虐我的键盘 %>_<% 
  */
  now=dist[x];
  
  if (now<p[x].r)
  {
    cx=p[x].c;
    rx=now;
    nx=p[x].r;
  }
  else 
  {
    rx=(now-p[x].r)%(p[x].time[2]);
    cx=1-p[x].c;
	if (rx>=p[x].time[1-p[x].c])
	{
	  rx-=p[x].time[1-p[x].c];
      cx=1-cx;
	}
	nx=now+p[x].time[cx]-rx;
  }
  
  if (now<p[y].r)
  {
    cy=p[y].c;
    ry=now;
    ny=p[y].r;
  }
  else
  {
    ry=(now-p[y].r)%(p[y].time[2]);
    cy=1-p[y].c;
    if (ry>=p[y].time[1-p[y].c])
    {
	  ry-=p[y].time[1-p[y].c];
	  cy=1-cy;
	}
	ny=now+p[y].time[cy]-ry;
  }
  if (cx==cy)
    return now;
  if (nx<ny)
    return nx;
  if (nx==ny)//当前变化时间相同,但是我们只是运行了每个点周期的一半,即我们只是把蓝色变成紫色,或者把紫色变成蓝色的时间相同,可能在另一半不同
  {
    nx=nx+p[x].time[1-cx];
    ny=ny+p[y].time[1-cy];
    if (nx==ny) //周期性可知确实是一直不可走的
      return -1;
    if (nx<ny)
      return nx;
    else
      return ny;
  }
  if (nx>ny)
    return ny;
} 
蒽,上面这段代骂确实是整个程序的核心部分,有很多版本的写法,这个只不过是其中一个。

下面是AC代码

<script src="https://code.csdn.net/snippets/505407.js"></script>

对于出现的一些逗B错误进行小结

【各种错误】
WA test5
额,真是没有想到前四个点有多弱,我把无向图存成有向图,时间判断忘记刚好到变灯时刻需要变灯(举例 若 5秒中时变灯,当时间为5秒时,已经变灯)
呵呵,我能说SGU格式错误很逗么。。。

额,SGU的PE真是醉人!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值