题目链接:

http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=16530

题意:

给定每个点最初的颜色,最初颜色持续时间,以及每个颜色的持续时间。每个点的颜色蓝紫交替,只有等待到一条路的两个端点颜色相同才能通行。到达某点时颜色恰好变色,则按照变色之后的颜色考虑。

给定道路的花费,问最少需要多少时间。

分析:

最短路问题。

dijk可做,麻烦之处在于要加上等待时间。对于每个点,判断相邻点颜色是否一致,不一致则选取当前颜色持续时间较短的一个作为等待时间。颜色相同的循环周期最多3次,3次之后颜色仍然无法一致则该路不通。

注意点数很少,边数很多,肯定有重边存在,选择邻接矩阵的形式。

代码:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
#define sa(a) scanf("%d", &a)
#define fi first
#define se second
#define MEM(a, b) memset(a, b, sizeof(a));
typedef pair<int, int >p;
const int maxn = 300 + 5, INF = 0x3f3f3f3f;
struct junction{int color; int r; int t[2];};
junction j[maxn];
int pa[maxn];
int dist[maxn];
int ss, tt;
int mm[maxn][maxn];
int getcolor(int time, int u)
{
if(time < j[u].r) return j[u].color;
int res = (time - j[u].r) % (j[u].t[0] + j[u].t[1]);
if(res < j[u].t[1 - j[u].color]) return 1 - j[u].color;
return j[u].color;
}
int hold(int u, int v, int time)
{
int ans = 0;
int cnt = 0;
int res1, res2, res;
while(cnt < 3){
int cc = getcolor(time, u);
int ccc = getcolor(time, v);
if(cc == ccc) return ans;
if(time< j[v].r) res1 = j[v].r - time;
else{
res = (time - j[v].r) % (j[v].t[0] + j[v].t[1]);
if(ccc == j[v].color) res1 = j[v].t[0] + j[v].t[1] - res;
else res1 = j[v].t[ccc] - res;
}
if(time < j[u].r) res2 = j[u].r - time;
else{
res = (time - j[u].r) % (j[u].t[0] + j[u].t[1]);
if(cc == j[u].color) res2 = j[u].t[0] + j[u].t[1] - res;
else res2 = j[u].t[cc] - res;
}
ans += min(res1, res2);
time += min(res1, res2);
cnt++;
}
return -1;
}
void dijkstra(int n)
{
priority_queue<p>q;
q.push(p(0,ss));
dist[ss] = 0;
while(!q.empty()){
p t = q.top();q.pop();
int u = t.se;
if(t.fi > dist[u]) continue;
for(int i = 1; i <= n;i++){
if(mm[u][i] == INF) continue;
int tmp = hold(i, u, dist[u]);
if(tmp == -1) continue;
if(mm[i][u] + tmp + dist[u] < dist[i]){
pa[i]=u;
dist[i] = mm[i][u] + tmp + dist[u];
q.push(p(dist[i], i));
}
}
}
}
void init()
{
MEM(pa, -1);
MEM(dist, 0x3f);
MEM(mm, 0x3f);
}
void output(int t)
{
if(t == -1) return;
output(pa[t]);
printf("%d ", t);
}
int main (void)
{
sa(ss),sa(tt);
init();
int n, m; sa(n),sa(m);
char c;
int a, b, d, t;
getchar();
for(int i = 1; i <= n; i++){
if(getchar() == 'B') t = 0;
else t = 1;
scanf("%d%d%d", &a, &b, &d);
j[i].color = t;
j[i].r = a;
j[i].t[0] = b;
j[i].t[1] = d;
getchar();
}
for(int i = 0; i < m; i++){
scanf("%d%d%d", &a, &b, &d);
mm[a][b] = mm[b][a] = d;
}
dijkstra(n);
if(dist[tt] == INF) return printf("0\n"), 0;
printf("%d\n", dist[tt]);
output(tt);
return 0;
}

SGU 103 Traffic Lights【最短路】的更多相关文章

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

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

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

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

  3. sgu 103 Traffic Lights

    这道题难得不是算法,而是处理. 题意就是让你求最短路,只有当两个点在某一秒颜色相同时,这条边才可以通行,输入首先给你 起点和终点, 然后给你 点数和边数, 接下来 n 行 初始颜色,初始颜色持续时间, ...

  4. 快速切题 sgu103. Traffic Lights 最短路 难度:1

    103. Traffic Lights Time limit per test: 0.25 second(s)Memory limit: 4096 kilobytes input: standardo ...

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

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

  6. Traffic Lights

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

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

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

  8. LightOJ 1074 Extended Traffic (最短路spfa+标记负环点)

    Extended Traffic 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/O Description Dhaka city ...

  9. Codeforces 954D Fight Against Traffic(BFS 最短路)

    题目链接:Fight Against Traffic 题意:有n个点个m条双向边,现在给出两个点S和T并要增加一条边,问增加一条边且S和T之间距离不变短的情况有几种? 题解:首先dfs求一下S到其他点 ...

随机推荐

  1. c++设计模式:策略模式

    1.主要思想:例如针对不同的算法,创建不同的类. #include <iostream> using namespace std; // The abstract strategy cla ...

  2. CF549G Happy Line

    传送门 解题思路 题意大概就是给你个数列,你可以随意交换i,i+1,交换后位于第i+1位的数字+1,位于第i位的数字-1,问最终能否形成一个不下降序列并输出.设初始数列中两个位置x,y最终交换后的位置 ...

  3. java的boolean和Boolean

    boolean是基本数据类型Boolean是它的封装类,和其他类一样,有属性有方法,可以new,例如: Boolean bl= new Boolean("true"); // bo ...

  4. Elasticsearch连接类(带密码)

    /** * 获取ES连接类 * * @author 陈康 * @description * @create 2019/08/15 **/ @Component("ElasticsearchR ...

  5. 006-使用python编写一个猜数字的程序

    题目:随机生成一个数字,共有三次机会对该数字进行猜测. #功能点# 1.猜错的时候给出提示,告诉用户输入的值是大了还是小了# 2.最多提供三次机会# 3.随机生成需要猜的数字答案 编写思路: 1.刚开 ...

  6. 出现$(#form).validate is not a function的问题

    最近为项目写cms系统,在新增/编辑文章的页面,一些input诸如文章题目,作者等等需要验证是否已经填写,于是使用jquery.validate.js来做这个工作,自己写了个验证的validate.j ...

  7. 解释器模式(Interpreter、Context、Expression)

    (给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子.) 解释器模式的定义是一种按照规定语法进行解析的方案,在现在项目中使用的比较少,其定义如下: Given ...

  8. vagrant简介

    什么是vagrant? 简单理解,就是可以通过Vagrant这个工具管理虚拟机,比如说想创建一个centos环境的虚拟机,不需要安装系统这么麻烦,通过vagrant可以快速创建 官网地址:https: ...

  9. 【模板】倍增LCA [2017年5月计划 清北学堂51精英班 Day3]

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  10. 洛谷P1650 赛马[2017年5月计划 清北学堂51精英班Day1]

    P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...