Description
moreD城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由 2n 条地铁线路构成,组成了一个 n 纵 n 横的交通网。如下图所示,这 2n 条线路每条线路都包含 n 个车站,而每个车站都在一组纵横线路的交汇处。
出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有 m 个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行 1 站需要 2 分钟,而站内换乘需要步行 1 分钟。 你的最后一个作业就是算出,在不中途出站的前提下,从学校回家最快需要多少时间(等车时间忽略不计)。
Input
第一行有两个整数 n, m。接下去 m 行每行两个整数 x, y,表示第 x 条横向线路与第 y 条纵向线路的交汇站是站内换乘站。接下去一行是四个整数 x1, y1, x2, y2。表示从学校回家时,在第 x1条横向线路与第 y1 条纵向线路的交汇站上车,在第 x2 条横向线路与第 y2 条纵向线路的交汇站下车。
Output
仅一个整数表示在合理选择线路的情况下,回家所需要的最少时间。如果无法在不出站换车的情况下回家则输出-1.
Sample Input
Sample Input 1 6 9 2 1 2 5 3 2 4 4 5 2 5 6 6 1 6 3 6 4 1 1 4 6 Sample Input 2 6 10 2 1 2 5 3 2 4 4 5 2 5 6 6 1 6 3 6 4 6 6 1 1 4 6 Sample Input 3 2 1 1 2 1 1 2 2
Sample Output
Sample Output 1 27 Sample Output 2 26 Sample Output 3 5
Data Constraint
Hint
对于10%的数据m=0
对于 30%的数据,n ≤ 50, m ≤ 1000;
对于 60%的数据,n ≤ 500, m ≤ 2000;
对于 100%的数据,n ≤ 20000, m ≤ 100000;
分析
看到换站要1单位时间就想到了网络流……的建图
我们把可以换乘的点拆成一条边就行了
跑SPFA轻松解决
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> using namespace std; const int N=2e4+10; const int M=1e5+10; struct Edge { int u,v,w,nx; }g[10*M]; int cnt,list[2*M],d[2*M]; bool b[2*M]; struct Point { int x,y,id; }a[M],s,t; int n,m; bool CMP1(Point a,Point b) { return a.x<b.x||a.x==b.x&&a.y<b.y; } bool CMP2(Point a,Point b) { return a.y<b.y||a.y==b.y&&a.x<b.x; } void Add(int u,int v,int w) { g[++cnt]=(Edge){u,v,w,list[u]};list[u]=cnt; g[++cnt]=(Edge){v,u,w,list[v]};list[v]=cnt; } void SPFA(int v0) { queue<int> q; while (!q.empty()) q.pop(); for (int i=1;i<=2*m+4;i++) d[i]=2147483647; d[v0]=0;b[v0]=1; q.push(v0); while (!q.empty()) { int u=q.front();q.pop(); for (int i=list[u];i;i=g[i].nx) if (d[g[i].v]>d[u]+g[i].w) { d[g[i].v]=d[u]+g[i].w; if (!b[g[i].v]) q.push(g[i].v); b[g[i].v]=1; } b[u]=0; } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i,Add(a[i].id,a[i].id+m+2,1); scanf("%d%d%d%d",&s.x,&s.y,&t.x,&t.y);s.id=m+1;t.id=m+2;Add(m+1,2*m+3,0);Add(m+2,2*m+4,0);a[m+1]=s;a[m+2]=t; sort(a+1,a+m+3,CMP1); for (int i=1;i<m+2;i++) if (a[i].x==a[i+1].x) Add(a[i].id,a[i+1].id,2*(a[i+1].y-a[i].y)); sort(a+1,a+m+3,CMP2); for (int i=1;i<m+2;i++) if (a[i].y==a[i+1].y) Add(a[i].id+m+2,a[i+1].id+m+2,2*(a[i+1].x-a[i].x)); SPFA(m+1); printf("%d\n",d[m+2]==2147483647?-1:d[m+2]); }