ural 1205. By the Underground or by Foot? Dijkstra

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1205


题意描述:给定N个地铁站点坐标,给定步行和地铁速度,求出从A点到B点最小消耗时间;


思路大致就是将距离换算成时间,抽象成单源最短路径问题;


AC代码(这个暴丑,懒得改了):

//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
#include <stack>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <iomanip>
using namespace std;


vector<vector<double> >v;
vector<pair<double, double> >cord;
vector<pair<int, double> >node;
vector<bool>vis;
const int NAL = 99999999;

int getOne(){		// 找下一个距离最短点
	double _min = NAL;
	int idx;
	for (size_t i = 0; i <vis.size();i++)
	if (vis[i] == false && _min>node[i].second){
		_min = node[i].second;
		idx = i;
	}
	return idx;
}

void func(){

	double onFoot, onMetro;
	cin >> onFoot >> onMetro;
	int N; 
	cin >> N;
	v.resize(N + 2, vector<double>(N + 2, NAL));
	cord.resize(N + 2);
	node.resize(N + 2, make_pair(-1, NAL));
	vis.resize(N + 2, false);

	for (int i = 1; i < N + 1; i++)
	{
		cin >> cord[i].first >> cord[i].second;
	}

	int src, tar;
	while (cin >> src >> tar&&src&&tar){		// 算地铁路径时间
		double tmp = sqrt(pow(cord[src].first - cord[tar].first, 2) + pow(cord[src].second - cord[tar].second, 2));
		tmp /= onMetro;
		v[src][tar] = tmp;
		v[tar][src] = tmp;
	}

	cin >> cord[0].first >> cord[0].second;
	cin >> cord[N + 1].first >> cord[N + 1].second;

	for (int i = 0; i <= N + 1; i++)
	for (int j = 0; j <= N + 1; j++){			//用步行时间更新状态
		if (i == j)continue;
		double tmp = sqrt(pow(cord[i].first - cord[j].first, 2) + pow(cord[i].second - cord[j].second, 2));
		tmp /= onFoot;
		if (v[i][j] > tmp)v[i][j] = tmp;
	}

	node[0].second = 0;
	//for (int i = 1; i <= N + 1; i++)
		//node[i].second = v[0][i];

	while (true){
		src = getOne();
		if (src == N + 1)break;
		vis[src] = true;
		
		for (int i = 0; i <= N + 1; i++)
		if (i != src&&vis[i] == false && node[i].second > node[src].second + v[src][i]){
			node[i].second = node[src].second + v[src][i];
			node[i].first = src;
		}
	}

	cout << setprecision(7) << fixed << node[src].second << endl;
	stack<int>ans;
	while (node[src].first != -1){
		src = node[src].first;
		ans.push(src);
	}

	ans.pop();
	cout << ans.size();
	while (!ans.empty()){
		cout << ' ' << ans.top();
		ans.pop();
	}
	cout << endl;

}

int main(){

	//freopen("out.txt", "w", stdout);
	//freopen("in.txt", "r", stdin);

	func();

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值