UVA 12661 Funny Car Racing

很巧妙的一道题目,主要考察的是迪杰斯特拉算法,但是要注意几个点:第一,通过某一条路的时间可能比该条路开放的时间要长,也就是说,不论怎么样,这条路是不能够通过的,所以就直接舍弃;第二,判断是否能够在合适的时间范围内通过需要用到取余的操作,同时如果能够在当前直接通过不需要等待与需要等待,这两种情况下对到达下一个节点的时间的计算是不一样的,这一部分要注意,具体实现见如下代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;

class Edge{
public:
	int from, to, open, close, time;
};

class Node{
public:
	int length, id;
	bool operator< (const Node& a) const{
		return length > a.length;
	}
};

class Solve{
public:
	int n, m, s, t;
	vector<Edge> edge;
	vector<int> G[310];
	const int Inf = 30000005;
	int Dijkstra(){
		priority_queue<Node,vector<Node>> q;
		bool visit[310];
		int dist[310];
		for (int i = 0; i < 310; i++) dist[i] = Inf;
		memset(visit, 0, sizeof(visit));
		Node temp;
		temp.id = s;
		dist[s] = 0;
		temp.length = 0;
		q.push(temp);
		while (!q.empty()){
			temp = q.top();
			q.pop();
			if (visit[temp.id]) continue;
			visit[temp.id] = true;
			for (int i = 0; i < G[temp.id].size(); i++){
				int ide = G[temp.id][i];
				Node temp2;
				int open = edge[ide].open, close = edge[ide].close, time = edge[ide].time;
				if (time > open) continue;
				int from = edge[ide].from, to = edge[ide].to;
				temp2.id = to;
				if (temp.length % (open + close) + time <= open){
					temp2.length = temp.length+ time;
					if (dist[to] > temp2.length){
						dist[to] = temp2.length;
						q.push(temp2);
					}
				}
				else{
					temp2.length = temp.length + open + close + time - temp.length % (open + close);
					if (dist[to] > temp2.length){
						dist[to] = temp2.length;
						q.push(temp2);
					}
				}
			}
		}
		return dist[t];
	}

	void Init(){
		edge.clear();
		for (int i = 0; i < 310; i++) G[i].clear();
		for (int i = 0; i < m; i++){
			Edge temp;
			cin >> temp.from >> temp.to >> temp.open >> temp.close >> temp.time;
			edge.push_back(temp);
			G[temp.from].push_back(edge.size()-1);
		}
	}

	int Deal(){
		Init();
		int ans = Dijkstra();
		return ans;
	}
};

int main(){
	Solve a;
	int Case = 0;
	while (cin >> a.n >> a.m >> a.s >> a.t){
		Case++;
		int res = a.Deal();
		cout << "Case " << Case << ": " << res << endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值