Traffic Lights - SGU 103(最短路)
题目大意:有一个城市的路线图,有N个交叉点,每两个交叉点之间只有一条路,现在想从交点u去交点v,不过这个路的交通比较特别,每个路都有一个交通灯,灯有两种颜色,蓝色和紫色,例如一条路线在交点s,t之间,如果想从s走到t,那么只有等s和t的交通灯的颜色一致的时候才可以从s走,求出来从u到v的最短时间。
分析:比较明显能看出来是一个最短路问题,不过里面夹杂的这个交通灯比较恶心,要随时能求出来两点点下一个相同颜色的时间,如果使用时间去枚举无疑是个比较笨的方法,注意到有个剩余时间,并且交通灯的每种颜色存在的最大值是100,所以可以判断出,一定会有重复情况出现,比如s剩余a,t剩余b,这种状态再次出现不会超过200次蓝紫灯循环,所以只需要枚举200次即可,如果还是找不带相同颜色,那么就说明这条路不能行走。ps.时间内存都比较小,边数比较多,所以邻接矩阵比连接表更省内存,注意有可能会有重边的情况。
代码如下:
=========================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = ;
const int oo = 1e9+; struct Junction
{
int op;///等于0是B, 等于1代表P
int Last;///剩余时间
int t[];///两种灯的转换时间 Junction NewOp(int time)
{///time时刻的状态
Junction res;
if(time >= Last)
{///当前时间大于剩余时间,等于的时候也需要转变成下一个灯
time -= Last;
time %= (t[]+t[]); if(time >= t[op^])
{
res.op = op;
res.Last = t[op] - (time-t[op^]);
}
else
{
res.op = op^;
res.Last = t[op^]-time;
}
}
else
{
res.op = op;
res.Last = Last - time;
} res.t[] = t[], res.t[] = t[]; return res;
}
int SameColor(Junction a, Junction b)
{///两个路灯下个相同颜色最少需要时间,-1表示不可能相同
///因为中间涉及到值得改变,所以不使用指针
int i, time=; for(i=; i<; i++)
{
if(a.op == b.op)
return time;
else if(a.Last >= b.Last)
{
time += b.Last;
a.Last -= b.Last;
b.Last = ;
}
else if(a.Last < b.Last)
{
time += a.Last;
b.Last -= a.Last;
a.Last = ;
} if(a.Last == )
{
a.op ^= ;
a.Last = a.t[a.op];
}
if(b.Last == )
{
b.op ^= ;
b.Last = b.t[b.op];
}
} return -;
}
}; Junction p[MAXN];///交叉点
int N;///交叉点个数
int G[MAXN][MAXN]; void Dij(int start, int end)
{
int dist[MAXN], path[MAXN]={};
int visit[MAXN]={}; for(int i=; i<=N; i++)
dist[i] = oo;
dist[start] = ; for(int t=; t<N; t++)
{
int index=start, Min=oo; for(int i=; i<=N; i++)
{
if(visit[i] == false && dist[i] < Min)
{
Min = dist[i];
index = i;
}
} if(visit[index])
break;
visit[index] = true; Junction u = p[index].NewOp(dist[index]), v; for(int i=; i<=N; i++)
{
if(!visit[i] && G[index][i] != oo && dist[i]>dist[index]+G[index][i])
{
v = p[i].NewOp(dist[index]);
int time = u.SameColor(u, v); if(time != - && dist[i] > dist[index]+G[index][i]+time)
{
dist[i] = dist[index] + G[index][i] + time;
path[i] = index;
}
}
}
} if(dist[end] == oo)
printf("0\n");
else
{
printf("%d\n", dist[end]); int k=, ans[MAXN]; while(end)
{
ans[k++] = end;
end = path[end];
} for(int i=k-; i>=; i--)
printf("%d%c", ans[i], i==?'\n':' ');
}
} int main()
{
int M, start, end;
char s[]; scanf("%d%d%d%d", &start, &end, &N, &M); for(int i=; i<=N; i++)
{
scanf("%s%d%d%d", s, &p[i].Last, &p[i].t[], &p[i].t[]);
p[i].op = (s[]=='B' ? : );
} int u, v, len; for(int i=; i<=N; i++)
for(int j=; j<=N; j++)
G[i][j] = oo; while(M--)
{
scanf("%d%d%d", &u, &v, &len);
G[u][v] = G[v][u] = min(G[u][v], len);
} Dij(start, end); return ;
}
Traffic Lights - SGU 103(最短路)的更多相关文章
- POJ1158 城市交通Traffic lights IOI 1999 (最短路)
POJ1158 城市交通Traffic lights IOI 1999 (最短路) (1) 问题描述(probolem) 在d城里交通的安排不同寻常,城中有路口和路口之间的道路,再任意两个不同的路口之 ...
- sgu 103 Traffic Lights 解题报告及测试数据
103. Traffic Lights Time limit per test: 0.25 second(s) Memory limit: 4096 kilobytes 题解: 1.其实就是求两点间的 ...
- 快速切题 sgu103. Traffic Lights 最短路 难度:1
103. Traffic Lights Time limit per test: 0.25 second(s)Memory limit: 4096 kilobytes input: standardo ...
- Traffic Lights
Traffic Lights time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- SGU 103.Traffic Lights(最短路)
时间: 0.50 second(s) 空间: 4096 kilobytes 输入: 标准输入 输出: 标准输出 Dingiville 城市的交通规则非常奇怪,城市公路通过路口相连,两个不同路口之间最多 ...
- SGU 103 Traffic Lights【最短路】
题目链接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=16530 题意: 给定每个点最初的颜色,最初颜色持续时间,以 ...
- sgu 103 Traffic Lights
这道题难得不是算法,而是处理. 题意就是让你求最短路,只有当两个点在某一秒颜色相同时,这条边才可以通行,输入首先给你 起点和终点, 然后给你 点数和边数, 接下来 n 行 初始颜色,初始颜色持续时间, ...
- sgu 185 最短路建网络流
题目:给出一个图,从图中找出两条最短路,使得边不重复. 分析:既然是最短路,那么,两条路径上的所有节点的入边(s,x).出边(x,e)必定是最优的,即 dis[x] = dis[s]+edge_dis ...
- TRAFFIC LIGHTS POJ 1158
题目大意: 在Dingilville 城市安排是一种不同寻常的方式,每个交叉路口有一条道路连接,一条道路最多连接两个不同的交叉路口.每个交叉路口不能连接他自己.道路旅行一端到另一端的时间是相同的,任何 ...
随机推荐
- C++Primer学习笔记
一.开始 二.基础 三.常用库 四.其他 五.附录
- Binary Tree Inorder Traversal 解题思路 ×
问题: 非递归中序遍历二叉树 思路: 1.大循环,判断节点是否为空,栈是否为空 2.不为空:点进栈,向左走 3.为空:为空,出栈,读取值,向右走
- python基础 [Alex视频]
vi hello.py#!/usr/bin/env pythonprint "hello world!"while True: print("hello world!&q ...
- mac os x 10.9.1 安装 Homebrew软件包管理工具及brew安装maven3.1.1
Mac OSX上的软件包管理工具,安装软件或者卸载软件. 打开终端输入(如不行,可参考homebrew官网): ruby -e "$(curl -fsSL https://raw.githu ...
- 2016022608 - redis字符串命令集合
redis字符串命令: Redis字符串命令用于在Redis管理字符串值.使用Redis字符串命令的语法如下所示: redis 127.0.0.1:6379> COMMAND KEY_NAME ...
- 在IT学习中的“认识论”
先有“感性认识”,再有“理性认识”.这句经典认识论,在IT领域应用广泛. 一个项目,首先是分析需求,也就是功能层面,这相当于先有“感性认识”:然后才是具体的技术实现,也就是“理性认识”. IT学习分析 ...
- 扩展原生js的一些方法
扩展原生js的Array类 Array.prototype.add = function(item){ this.push(item); } Array.prototype.addRange = fu ...
- java相关各种页面跳转
AK相信页面跳转在这个圈圈圆圆里是个地球人都能经常遇到的事,AK也在平时的工作学习中记录了一些,这里就做一个小小的总结,有任何的疑问和质疑都希望您能告诉我,不用担心后果,必定至少您还能理我,AK万分感 ...
- C++中四种类型转换方式
类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...
- 【关于JavaScript】常见表单用户名、密码不能为空
在论坛等系统的用户注册功能中,如果用户忘记填写必填信息,如用户名.密码等,浏览器会弹出警告框,提示用户当前有未填信息. 这个典型的应用就是通过JavaScript实现的.如图所示是一个简单的用户注册页 ...