SGU 103 Traffic Lights【最短路】
2016-04-24 10:58
435 查看
题目链接:
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; }
相关文章推荐
- S折交叉验证 简介
- 免费科研资料下载网站记录
- SQL第三节课
- Linux 中 /bin、/sbin、/usr/sbin、/usr/bin的区别
- 注册一个结构类型 Q_DECLARE_METATYPE(Type)
- QT 工程文件元素配置项 Creating Project Files
- 【Arduino官方教程第一辑】示例程序 2-4 数字引脚上拉电阻
- JS中的call、apply、bind方法
- 第八周学习进度
- sublime text使用及常见问题
- JSON Models Example
- 数据结构(一)
- SQL第二节课
- 简单谈谈如何利用h5实现音频的播放
- 自定义 Material Design风格的提示框
- 第三届H-star 程序设计竞赛初赛题解
- Qml 中模型数据加载的ThreeLoader.js
- jQuery 效果 - slideToggle() 方法
- 求数组的最大值 最小值问题 -Math方法
- 团队开发——个人工作总结06