题目

题目大意

轨道交通网络由 2n 条地铁线路构成,组成了一个 n 纵 n 横的交通网。如下图所示,这 2n 条线路每条线路都包含 n 个车站,而每个车站都在一组纵横线路的交汇处。

并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有 m 个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行 1 站需要 2 分钟,而站内换乘需要步行 1 分钟。

在不中途出站的前提下,从学校回家最快需要多少时间(等车时间忽略不计)。

[1.23] T3-回家

题目解析

很明显是一个最短路,主要是在构图上需要解决

把换乘车站(包括起点和终点)的坐标分为2个点,一个点连纵坐标相同的点,另一个点连横坐标相同的点,距离为2点的距离,而同属一个坐标的两个点的距离为1(起点和终点为0)

在这样构图以后,跑一个最短路即可

代码

#include<bits/stdc++.h>
using namespace std;
struct A
{
	int x,y,id;
}a[200005];
struct V
{
	int s,i;
};
vector<V> dis[200005];
queue<int> q;
int n,m,f[200005];
bool flag[200005];
void add1(int x)
{
	V s;
	s.s=2*(a[x+1].y-a[x].y);
	s.i=a[x+1].id;
	dis[a[x].id].push_back(s);
	s.i=a[x].id;
	dis[a[x+1].id].push_back(s);
}
void add2(int x,int p)
{
	V s;
	s.s=2*(a[x+1].x-a[x].x);
	s.i=a[x+1].id+p;
	dis[a[x].id+p].push_back(s);
	s.i=a[x].id+p;
	dis[a[x+1].id+p].push_back(s);
}
bool cmp1(A a,A b)
{
	return a.x==b.x?a.y<b.y:a.x<b.x;
}
bool cmp2(A a,A b)
{
	return a.y==b.y?a.x<b.x:a.y<b.y;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m+2;i++)
	{
	  cin>>a[i].x>>a[i].y;
	  a[i].id=i;
	  a[i+m+2]=a[i];
	  a[i+m+2].id=i+m+2;
	  V s;
	  if(i>m) s.s=0;
	  else s.s=1;
	  s.i=i+m+2;
	  dis[i].push_back(s);
	  s.i=i;
	  dis[i+m+2].push_back(s);
	}
	sort(a+1,a+m+3,cmp1);
	for(int i=1;i<m+2;i++)
	 if(a[i].x==a[i+1].x)
	  add1(i);
	sort(a+1,a+m+3,cmp2);
	for(int i=1;i<m+2;i++)
	 if(a[i].y==a[i+1].y)
	  add2(i,m+2);
	q.push(m+1);
	memset(f,0x3f,sizeof(f));
	f[m+1]=0;
	while(!q.empty())
	{
	  int id=q.front();
	  q.pop();
	  flag[id]=0;
	  for(int i=0;i<dis[id].size();i++)
	  {
	  	if(f[id]+dis[id][i].s<f[dis[id][i].i])
	  	{
	  	  f[dis[id][i].i]=f[id]+dis[id][i].s;
	  	  if(!flag[dis[id][i].i])
	  	  {
	  	    q.push(dis[id][i].i);
		    flag[dis[id][i].i]=1;	
		  }
		}
	  }
	}
	if(f[2*m+4]==f[0])
	 cout<<-1;
	else
	 cout<<f[2*m+4];
	return 0;
}

相关文章: