uva12661
来源:互联网 发布:java电脑版86安装包 编辑:程序博客网 时间:2024/04/30 16:28
题目描述:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47070
/*solution: 本题就是最短路径问题,但是在边的权值上做了文章,并不单单只是考虑权值 而且还要考虑到达一条边的“阀门”时,是否要在门前进行等待,此时权值要加上 等待的时间。关于dijkstra详见模板开头注释note: 1.注意需要对是否应该在路口等待做判断,即对权值做判断。 2.注意对是否能够走一条路的条件“You must enter a road when it’s open, and leave it before it’s closed again.” 3.对权值的判断此题有如下集中情况。一是不能通过这条路,即走完前面一条路所花时间 太长,还没到路口。不符合题目中条件,所以此路不能走;二是能够走这条路,但是需要在走下一段路时在路口等待。 三是不需要等待就可以直接进入下一路 4.时间状况的判断,详见代码旁边注释date: 2016/4/21*/#include <iostream>#include <cstdio>#include <queue>#include <cstring>using namespace std;const int maxn = 300 + 5;const int maxm = 50000 + 5;const int INF = 99999999;int n, m, s, t, dist[maxn], vis[maxn];struct Edge { //定义结构体用来存储边 int from, to, open, close, time;};vector<int> G[maxn];vector<Edge> edges;struct HeapNode { //定义该结构体是为了作为优先队列中的元素类型 int dist, u; bool operator < (const HeapNode& rhs) const { return dist > rhs.dist; //仍然定义最小堆的比较器 }};int dijkstra() { priority_queue<HeapNode> q; for(int i = 0; i <= n; i++) dist[i] = INF; dist[s] = 0; memset(vis, 0, sizeof(vis)); q.push((HeapNode) {0, s}); //将{0, s} “ 打包 ” 成一个HeapNode类型压入队列,其中的dist成员和u成员值分别为0,s while(!q.empty()) { HeapNode x = q.top(); q.pop(); int u = x.u; if(vis[u]) continue; vis[u] = 1; for(int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; int time = e.time; int open = e.open; int close = e.close; int from = e.from; int to = e.to; if(time > open) continue; //行走这条路所花费的时间大于关闭路径的时间,所以此路不通。这是题目中告知的一条边是否能走的条件 if(dist[from] % (open + close) + time <= open) { //不用等待直接进入该路径 if(dist[to] > dist[from] + time) { //直接对该边进行松弛操作 dist[to] = dist[from] + time; q.push((HeapNode) {dist[to], to}); } } else { //需要在“阀门前”等待一会 int wt = dist[from] + time + open + close - dist[from] % (open + close); if(dist[to] > wt) { //“open + close - dist[from] % (open + close)”是等待的时间,所以wt是通过需要的总时间 dist[to] = wt; q.push((HeapNode) {dist[to], to}); } } } } return dist[t];}int main(){ int kase = 0; while(scanf("%d%d%d%d", &n, &m, &s, &t) == 4) { for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); //先对要使用的vector容器进行初始化 Edge tmp; //开始读入数据 for(int i = 0; i < m; i++) { scanf("%d%d%d%d%d", &tmp.from, &tmp.to, &tmp.open, &tmp.close, &tmp.time); edges.push_back(tmp); int m = edges.size(); G[tmp.from].push_back(m - 1); //注意记录的是边在edges容器中的下标,这样是为了能够访问到权值 } int ans = dijkstra(); //调用dijkstra返回答案 printf("Case %d: %d\n", ++kase, ans); //注意格式 } return 0;}
0 0
- uva12661
- UVA12661
- uva12661 Dijkstra
- uva12661 最短路
- UVA12661 有趣的赛车比赛
- UVa12661: Funny Car Racing 题解
- 最短路 uva12661 Funny Car Racing
- 除去字符串里相同的字符
- 删除 SQL Server 表中的重复行
- 长文干货!走近人脸检测:从VJ到深度学习(上)(下)
- 万恶的开源druid,去die
- wincache xcache 性能测试
- uva12661
- msp430的printf函数的简单移植
- IEEE极限编程之The pipeline-动态规划思想
- LeetCode *** 209. Minimum Size Subarray Sum
- ubuntu 部署L2TP亲测
- 剑指Offer——二维数组查找
- Content Comment Design
- 彻底解决_OBJC_CLASS_$_某文件名", referenced from:问题(转)
- 通过sqli-labs学习sql注入——基础挑战之less1-10