【L - Subway】

80 篇文章 0 订阅
80 篇文章 0 订阅

完!结!撒!花!!

算法:Dijkstra

思路:

  • 只会走给出的坐标,所以把所有给出的坐标存成点再根据要求建边,求最短路即可。
  • 注意:
    1. “rounded to the nearest minute” 是四舍五入,要加上 0.5,再转换成 int 输出。不加 0.5 会 WA
    2. map 的用法。

代码:

  • 391ms 1164kB
//391ms			1164kB


#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#define INF 100000000

using namespace std;

const int maxn = 205;
typedef pair<int,int> Ptype;
const double WR = 10/3.6;//walk_rate in SI
const double SR = 40/3.6;//subway_rate in SI

int Sx,Sy,Ex,Ey;
map<Ptype , int> MP;//x,y,id
double mp[maxn][maxn];// s

struct NODE{
	int id;
	double dis;
	NODE(int id,double dis) : id(id) , dis(dis) {} ;
	friend bool operator > (NODE a , NODE b){
		return a.dis > b.dis;
	}
};
int cnt=0;//id
double dis[maxn];
priority_queue<NODE , vector<NODE> , greater<NODE> > Q ;

double IJK(){
	for(int i=1;i<maxn;i++)
		dis[i] = INF; 
	Q.push(NODE(1,0));dis[1]=0;
	while(Q.size()){
		NODE cur = Q.top() ; Q.pop();
		if(cur.dis > dis[cur.id])
			continue;
		for(int i=1 ; i<=cnt ; i++){
			if(dis[i] > dis[cur.id] + mp[cur.id][i]){
				dis[i] = dis[cur.id] + mp[cur.id][i];
				Q.push(NODE(i , dis[i]));
			}
		}
	}
	return dis[2] / 60;
}

int main(){
	for(int i=1;i<maxn;i++)
		for(int j=1;j<maxn;j++)
			mp[i][j] = mp[j][i] = INF;
	cin>>Sx>>Sy>>Ex>>Ey;
	MP[Ptype(Sx,Sy)] = ++cnt;//	1
	MP[Ptype(Ex,Ey)] = ++cnt;//	2
	int ux,uy,vx,vy;
	int uid,vid;
	while(cin>>ux>>uy){
		while(cin>>vx>>vy && (vx!=-1 || vy != -1)){
			if(MP.count(Ptype(ux,uy)))
				uid = MP[Ptype(ux,uy)];
			else
				MP[Ptype(ux,uy)] = uid = ++cnt;
			if(MP.count(Ptype(vx,vy)))
				vid = MP[Ptype(vx,vy)];
			else
				MP[Ptype(vx,vy)] = vid = ++cnt;
			
			double w = sqrt((ux-vx)*(ux-vx) + (uy-vy)*(uy-vy)) / SR;
			mp[uid][vid] = mp[vid][uid] = w;
			
			ux = vx , uy = vy; 
		}
	}
	for(int i=1;i<=cnt;i++){
		for(int j=1;j<=cnt;j++){
			if(mp[i][j] == INF){
				double ux,uy,vx,vy;
				map<Ptype,int>::iterator pi,pj;
				for(pi = MP.begin() ; pi!=MP.end() ; pi++){
					if(pi->second == i){
						ux = pi->first.first;
						uy = pi->first.second;
						break;
					}
				}
				for(pj = MP.begin() ; pj!=MP.end() ; pj++){
					if(pj->second == j){
						vx = pj->first.first;
						vy = pj->first.second;
						break;
					}
				}
				mp[i][j] = mp[j][i] = sqrt((ux-vx)*(ux-vx) + (uy-vy)*(uy-vy)) / WR;
			}
		}
	}
	cout<<(int)(IJK()+0.5)<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值