103. Traffic Lights

Time limit per test: 0.25 second(s)
Memory limit: 4096 kilobytes
input: standard
output: standard

In the city of Dingilville the traffic is arranged in an unusual way. There are junctions and roads connecting the junctions. There is at most one road between any two different junctions. There is no road connecting a junction to itself. Travel time for a road is the same for both directions. At every junction there is a single traffic light that is either blue or purple at any moment. The color of each light alternates periodically: blue for certain duration and then purple for another duration. Traffic is permitted to travel down the road between any two junctions, if and only if the lights at both junctions are the same color at the moment of departing from one junction for the other. If a vehicle arrives at a junction just at the moment the lights switch it must consider the new colors of lights. Vehicles are allowed to wait at the junctions. You are given the city map which shows:

  • the travel times for all roads (integers)
  • the durations of the two colors at each junction (integers)
  • and the initial color of the light and the remaining time (integer) for this color to change at each junction. 

    Your task is to find a path which takes the minimum time from a given source junction to a given destination junction for a vehicle when the traffic starts. In case more than one such path exists you are required to report only one of them.

    Input

    The first line contains two numbers: The id-number of the source junction and the id-number of the destination junction. The second line contains two numbers: NM. The following N lines contain information on N junctions. The (i+2)'th line of the input file holds information about the junction i : CiriCtiBtiP where Ci is either B for blue or P forpurple, indicating the initial color of the light at the junction i. Finally, the next M lines contain information on M roads. Each line is of the form: ijlij where i and j are the id-numbers of the junctions which are connected by this road. 2 ≤ N ≤ 300 where N is the number of junctions. The junctions are identified by integers 1 through N. These numbers are called id-numbers. 1 ≤ M ≤ 14000 where M is the number of roads. 1 ≤ lij ≤ 100 where lij is the time required to move from junction i to j using the road that connects i andj. 1 ≤ tiC ≤ 100 where tiC is the duration of the color c for the light at the junction i. The index c is either 'B' for blue or 'P' for purple. 1 ≤ riC ≤ tiC where riC is the remaining time for the initial color c at junction i.

    Output

    If a path exists:

  • The first line will contain the time taken by a minimum-time path from the source junction to the destination junction.
  • Second line will contain the list of junctions that construct the minimum-time path you have found. You have to write the junctions to the output file in the order of travelling. Therefore the first integer in this line must be the id-number of the source junction and the last one the id-number of the destination junction. 

    If a path does not exist:

  • A single line containing only the integer 0. 
    Example(s)
    sample input
    sample output
    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
    127
    1 2 4

题意:图,无自交,无向,在每个时间每个节点有一个信号灯,可能是绿色或者紫色,信号灯变化规律:蓝色持续一段时间接着是紫色,允许在信号灯同样颜色的时候离开一个节点通过路到达另一个节点,到达瞬间颜色可以不一样,如果到达瞬间颜色改变,按照新颜色计算,允许任意点停留,
你能得到的状态:
1 所有路径花费时间
2 每个节点灯的持续周期
3 每个节点灯的初始颜色和还剩多长时间第一次变颜色

思路:注意到这道题每个节点通向另一个节点耗时是容易得出的,而且过程有意义的只有最早到节点的时间,知道源点,到达点求最短路,最短路算法就可以了

注意状态转化,主要是考细心

实际用时:1h38min

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const ll inf=0x7ffffffffff;
const int maxn=305;
const int maxm=50000;
int n,m;
ll dis[maxn];//最小距离(时间)
int first[maxn];//邻接表
int nxt[maxm];
int to[maxm];
int cost[maxm];
int color[maxn];//初始颜色
int wait[maxn];//第一次变化时间
int time[maxn][2];//等待颜色
int pre[maxn];//路径回溯,前驱节点
queue<int >que;
int sups,supe;
char buff[3];//接收颜色用
int heap[maxn],len;
void dfs(int s){//路径回溯
if(s==sups){
len=0;
heap[len++]=s;
return ;
}
dfs(pre[s]);
heap[len++]=s;
}
int calcolor(int ttime,int s){//计算当前颜色
if(ttime<wait[s])return color[s];
ttime-=wait[s];
int c=color[s]^1;
ttime-=((int)ttime/(time[s][0]+time[s][1]))*(time[s][0]+time[s][1]);
if(ttime<time[s][c])return c;
return color[s];
}
int caltime(int ttime,int s){//计算变化颜色时间
if(ttime<wait[s])return wait[s]-ttime;
ttime-=wait[s];
int c=color[s]^1;
ttime-=((int)ttime/(time[s][0]+time[s][1]))*(time[s][0]+time[s][1]);
if(ttime<time[s][c])return time[s][c]-ttime;
return time[s][0]+time[s][1]-ttime;
}
void addedge(int f,int t,int c,int ind){
nxt[ind*2]=first[f];
cost[ind*2]=c;
to[ind*2]=t;
first[f]=ind*2;
nxt[ind*2+1]=first[t];
cost[ind*2+1]=c;
to[ind*2+1]=f;
first[t]=ind*2+1;
}
void spfa(){
fill(dis,dis+n+1,inf);
que.push(sups);
dis[sups]=0;
while(!que.empty()){
int s=que.front();que.pop();
int scolor=calcolor(dis[s],s);
for(int p=first[s];p!=-1;p=nxt[p]){
int tto=to[p];
int tcolor=calcolor(dis[s],tto);
if(scolor==tcolor){
if(dis[tto]>dis[s]+cost[p]){//颜色相同可以直接走
dis[tto]=dis[s]+cost[p];
pre[tto]=s;
que.push(tto);
}
}
else {
int stime=caltime(dis[s],s);
int ttime=caltime(dis[s],tto);
if(stime==ttime&&time[s][scolor^1]==time[tto][tcolor^1]&&time[s][scolor]==time[tto][tcolor])continue;//这两个节点同步变化,永远走不了
if(stime==ttime){//如果变化周期不一样而现在等待时间一样就多等一周期
stime+=time[s][scolor^1];
ttime+=time[tto][tcolor^1];
}
if(stime==ttime){//再多等一周期
stime+=time[s][scolor];
ttime+=time[tto][tcolor];
}
if(dis[tto]>dis[s]+min(stime,ttime)+cost[p]){//更新
dis[tto]=dis[s]+min(stime,ttime)+cost[p];
pre[tto]=s;
que.push(tto);
}
}
}
}
}
int main(){
while(scanf("%d%d",&sups,&supe)==2){
sups--;supe--;
memset(first,-1,sizeof(first));
scanf("%d%d",&n,&m);
for (int i=0;i<n;i++){
scanf("%s%d%d%d",buff,wait+i,time[i],time[i]+1);
if(buff[0]=='B')color[i]=0;
else color[i]=1;
}
for(int i=0;i<m;i++){
int f,t,c;
scanf("%d%d%d",&f,&t,&c);
f--;t--;
addedge(f,t,c,i);
}
spfa();
if(dis[supe]==inf)puts("0");
else {
printf("%I64d\n",dis[supe]);
dfs(supe);
for(int i=0;i<len;i++){
printf("%d%c",heap[i]+1,i==len-1?'\n':' ');
}
}
} return 0;
}

  

快速切题 sgu103. Traffic Lights 最短路 难度:1的更多相关文章

  1. 快速切题 poj 1003 hangover 数学观察 难度:0

    Hangover Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 103896   Accepted: 50542 Descr ...

  2. POJ1158 城市交通Traffic lights IOI 1999 (最短路)

    POJ1158 城市交通Traffic lights IOI 1999 (最短路) (1) 问题描述(probolem) 在d城里交通的安排不同寻常,城中有路口和路口之间的道路,再任意两个不同的路口之 ...

  3. sgu 103 Traffic Lights 解题报告及测试数据

    103. Traffic Lights Time limit per test: 0.25 second(s) Memory limit: 4096 kilobytes 题解: 1.其实就是求两点间的 ...

  4. Traffic Lights

    Traffic Lights time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  5. SGU 103.Traffic Lights(最短路)

    时间: 0.50 second(s) 空间: 4096 kilobytes 输入: 标准输入 输出: 标准输出 Dingiville 城市的交通规则非常奇怪,城市公路通过路口相连,两个不同路口之间最多 ...

  6. 快速切题 poj 2485 Highways prim算法+堆 不完全优化 难度:0

    Highways Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23033   Accepted: 10612 Descri ...

  7. Traffic Lights - SGU 103(最短路)

    题目大意:有一个城市的路线图,有N个交叉点,每两个交叉点之间只有一条路,现在想从交点u去交点v,不过这个路的交通比较特别,每个路都有一个交通灯,灯有两种颜色,蓝色和紫色,例如一条路线在交点s,t之间, ...

  8. 快速切题 sgu115. Calendar 模拟 难度:0

    115. Calendar time limit per test: 0.25 sec. memory limit per test: 4096 KB First year of new millen ...

  9. 快速切题 sgu113 Nearly prime numbers 难度:0

    113. Nearly prime numbers time limit per test: 0.25 sec. memory limit per test: 4096 KB Nearly prime ...

随机推荐

  1. max3232

    max3232采用专有低压差发送器输出级,利用双电荷泵在3.0V至5.5V电源供电时能够实现真正的RS-232性能,器件仅需四个0.1uF的外部小尺寸电荷泵电容.max3232确保在120kbps数据 ...

  2. java Request 获得用户IP地址

    public static String getIpAddress(HttpServletRequest request) { String ip = request.getHeader(" ...

  3. YOLOv1-darknet 内容解析

    目录 YOLOv1-darknet 内容解析 1. 核心思想 2. 特点 3. 缺点 4. 算法流程 5. 详细内容 6. 主要参考 YOLOv1-darknet 内容解析 1. 核心思想 目标检测分 ...

  4. 关于Java中System.gc() 与System.runFinalization()

    System.gc  : 告诉垃圾收集器打算进行垃圾收集,而垃圾收集器进不进行收集是不确定的.只是建议进行回收 System.runFinalization(): 网上搜了一下很多人都说强制调用已经失 ...

  5. Jmeter自动化测试 数据驱动测试,将数据存入csv文件中来调用,或将数据存在DB中进行调用

    1. 将测试的用例名称,测试请求方式,测试链接,预置数据,断言等都放到excel中,然后转成csv格式,在用Jmeter带的csv数据配置文件导入 运行之前将线程组中配置,线程数设置为1,循环的次数设 ...

  6. jsjl_for_ubuntu12.04

    1. VC++代码: #include <stdio.h> #include <windows.h> #include <wchar.h> void MoveMou ...

  7. 使用R的数据库查询

    JS 很多方法可以用R查询数据.这篇文章展示了三种最常见的方法: 运用 DBI 使用dplyr语法 使用R note book 背景 最近的一些软件包改进可以更轻松地将数据库与R一起使用.下面的查询示 ...

  8. 使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果

    在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的TabHost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义RadioButto ...

  9. 1月21日 Reference Data Type 数据类型,算法基础说明,二分搜索算法。(课程内容)

    Reference Datat Types 引用参考数据类型 -> 组合数据类型 Array, Hash和程序员自定义的复合资料类型 组合数据的修改: 组合数据类型的变量,不是直接存值,而是存一 ...

  10. Javascript基础一(2)

    循环语句 1.for循环 <script> //从1乘到100: //计数器 // var product = 1; // for(var i=1;i<=10;i++){ // pr ...