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 城市安排是一种不同寻常的方式,每个交叉路口有一条道路连接,一条道路最多连接两个不同的交叉路口.每个交叉路口不能连接他自己.道路旅行一端到另一端的时间是相同的,任何 ...
随机推荐
- SQL Server T-SQL高级查询【转】
高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student; --all 查询所有 select all sex from ...
- iOS,长按图片保存实现方法,轻松搞定!
1.添加手势识别: UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@s ...
- OpenCV Tricks[OpenCV 笔记3]
官方例程 事例程序位于opencv-3.1.0/samples/cpp/ 目录下,可以通过编译整个工程,编译所有的Sample Code 显示当前使用的OpenCV版本 CV_VERSION为标识当前 ...
- localStorage.ie6.js
!window.localStorage && function() { window.localStorage = {}; var prefix = 'data-userdata' ...
- juquery验证插件validation addMethod方法使用笔记
该方法有三个api接口参数,name,method,messages addMethod(name,method,message)方法 参数 name 是添加的方法的名字. 参数 method 是一个 ...
- 日期-用Datapicker实现前一天后一天
运用了JQuery UI Datepicker 插件和一些常用日期的方法.其中Datepicker的API具体可参考[http://api.jqueryui.com/datepicker/#optio ...
- PHP设计模式之:策略模式
<?phpabstract class Strategy{ public abstract function AlgorithmInterface();} class ConcreteSt ...
- socket+网路编程
1.网络编程: 通过某种计算机语言来实现不同设备间的资源共享和信息传递.计算机网络的创造可能比计算机本身意义更重大!!!(否则,你只能玩单机版游戏 OSI模型 OSI模型定义了不同计算机互联的标准,是 ...
- java printf与println的区别
Java中的println和printf的区别在于:println是用于输出参数内容,然后换行,其参数个数固定为一个.printf是用于输出带各种数据类型的占位符的参数,其参数个数是不定的.
- C语言笔记(二维数组与数值指针)
一.关于二维数组和二维数组区别 (1)一维数组在内存中是连续分布存储的,同样,二维数组也是在内存连续存储的.所以从内存的角度来分析,一维数组和二维数组其实没有本质区别. (2) 二维数组可以使用一维数 ...