Uva10801电梯换乘-最短路

题意:

有一层不超过100层的大楼, 有n个电梯,它们的速度都不同。 而且每个电梯只能到达指定的那些楼层,而且它们都有各自的速度(即上升一层或下降一层所用的时间)。 如果一个人在某层走出电梯,要换一个电梯乘,那么他要等60秒(不管要等的是那个电梯,即使是刚刚出来的那个电梯也要等60秒)。在0层搭电梯出发时不需要等待。
一个人从0层开始,目的地是k层, 现在要搭这些电梯,问最少需多少时间。

思路:

建图,最短路

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define fi first
#define se second
#define pii pair<int,int>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int maxn = 100+5;
int n, k, done[maxn], dis[maxn], T[maxn], w[maxn][maxn];

vector<int> vec[maxn];

// 图
struct Edge{
	int u, v;
	Edge(int a = 0, int b = 0):u(a),v(b){}
};
vector<Edge> edges;
vector<int> G[maxn];
void init(int a){
	for(int i = 0; i < a; ++i) G[i].clear();
	edges.clear();
}
void addEdge(int u, int v){
	edges.push_back(Edge(u,v));
	edges.push_back(Edge(v,u));
	int a = edges.size();
	G[u].push_back(a-2);
	G[v].push_back(a-1);
}

struct Node{
	int d, u;
	Node(int a = 0, int b = 0):u(a),d(b){}
	bool operator < (const Node& rhs) const{
		return d > rhs.d;
	}
};
int Dijkstra(int s ,int t){
	priority_queue<Node> Q;
	memset(dis, 0x3f, sizeof(dis));
	memset(done , 0, sizeof(done));
	dis[s] = 0;
	Q.push(Node(s,0));
	while(!Q.empty()){
		
		Node t = Q.top(); Q.pop();
		int u = t.u;
		if(done[u]) continue;
		done[u] = 1;
		for(int i = 0; i < G[u].size(); ++i){
			Edge& e = edges[G[u][i]];
			int v = e.v;
			int extra = 0;
			if(u != s) extra = 60;
			if(dis[v] > dis[u] + w[u][v] + extra){
				dis[v] = dis[u] + w[u][v] + extra;
				Q.push(Node(v, dis[v]));
			}
		}
	}
	return dis[t];
}


int main()
{
	freopen("in.txt","r",stdin);
	
	while(scanf("%d%d",&n,&k) == 2&&n){
		memset(w, 0x3f, sizeof(w));
		for(int i = 0; i < n; ++i) vec[i].clear();
		//init(n);
		for(int i = 0; i < n; ++i) scanf("%d",&T[i]);
		for(int i = 0; i < n; ++i){
			char ch;
			do{
				int u; scanf("%d",&u);
				vec[i].push_back(u);
			}while((ch = getchar()) != '\n');
		}
		// 建图 
		for(int p = 0; p < n; ++p){
			for(int i = 0; i < vec[p].size(); ++i){
				for(int j = i+1; j < vec[p].size(); ++j){
					int u = vec[p][i], v = vec[p][j];
					int cost = abs(vec[p][i] - vec[p][j]) * T[p];
					w[u][v] = w[v][u] = min(w[u][v], cost);
					addEdge(vec[p][i], vec[p][j]);
				}
			}
		}
		int s = 0, t = k;
		int ans = Dijkstra(s, t);
		if(ans == INF) printf("IMPOSSIBLE\n");
		else printf("%d\n",ans);
		//printf("%d %d",vec[0].size(), vec[1].size()); 
	}

	return 0;
}


猜你喜欢

转载自blog.csdn.net/CY05627/article/details/91832417
今日推荐