Description
给出一个二维图 已知m个矩阵覆盖部分区域 且这m个矩阵严格不相邻
在不碰到任一矩阵情况下 求给出两坐标间最短距离[曼哈顿距离]
Solution
40分做法
无视一切矩阵 求曼哈顿距离
好吧就是扯淡
100分做法
显然 不会出现“封死”的情况
而且题目求的是曼哈顿
也就是说 不可能向左走(不优秀)
有了这个结论的话…
考虑从左向右做一个扫描线 也就是顺次“推进”
可以用线段树维护一下可以走到的点所需花费
步步递进即可
另外 也很容易想到将矩阵划分成四个点
然而右边两个没有用(不会更新答案)
显然可以用队列一类的东西连边
没有环的出现
复杂度易证
请使用SPFA BFS
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define oo 2139062143
#define sqr(x) ((x)*(x))
#define abs(x) (((x)>=0)?(x):(-(x)))
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))
#define fo(i,x,y) for (int i = (x);i <= (y);++ i)
#define fd(i,x,y) for (int i = (x);i >= (y);-- i)
#define fm(i,x) for (int i = las[x];i;i = e[i].nex)
using namespace std;
typedef double db;
typedef long long ll;
const int N = 500500,Mo = 1001000;
int n,m,tot,sx,sy;
int data[Mo],dis[Mo];
int st,fin,ind[Mo],mem[Mo];
bool vis[Mo];
struct node{
int x,uy,dy;
}sq[N];
struct edge{
int to,nex,v;
}e[N * 5];
int las[N];
int read()
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;
int n=q*w;return n;
}
bool cmp(node x,node y)
{
return (x.x < y.x)||(x.x == y.x && x.uy == sy) || (x.x == y.x && x.uy != sy && x.uy > y.uy);
}
void spfa()
{
memset(dis,127,sizeof dis);
memset(vis,0,sizeof vis);
dis[st] = 0 ;
vis[st] = 1,data[1] = st;
int hd = 0,tl = 1;
while (hd ++ < tl)
{
int now = hd % Mo;
int x = data[now],t;
fm(i,x)
{
-- ind[t = e[i].to];
if (dis[x] + e[i].v < min(dis[t],dis[fin])) dis[t] = dis[x] + e[i].v;
if (!vis[t] && ind[t] == 0)
{
vis[t] = true;
data[(++ tl) % Mo] = t;
}
}
}
}
void link(int x,int y,int v)
{
e[++ tot].to = y,
e[tot].v = v,
e[tot].nex = las[x],
las[x] = tot;
++ ind[y];
}
void linking(int y,int past,int now,int dist)
{
dis[now] = dist;
fo(i,past + 1,n)
{
if (sq[i].dy < y && sq[i].uy > y)
{
bool p = false;
if (!mem[i]) mem[i] = ++ m,++ m,p = true;
if(abs(sq[i].uy - y) > abs(y - sq[i].dy))
{
link(now,mem[i],abs(sq[i].uy - y));
link(now,mem[i] + 1,abs(y - sq[i].dy));
}
else
{
link(now,mem[i] + 1,abs(y - sq[i].dy));
link(now,mem[i],abs(sq[i].uy - y));
}
if (p)
{
linking(sq[i].uy,i,mem[i],dist+abs(sq[i].uy-y));
linking(sq[i].dy,i,mem[i]+1,dist+abs(y-sq[i].dy));
}
break;
}
if (sq[i].dy == sy && sq[i].x == sx)
{
if (!fin) fin = ++ m;
link(now,fin,abs(sq[i].uy - y));
break;
}
}
}
int main()
{
freopen("bl.in","r",stdin);
freopen("bl.out","w",stdout);
sx = read(),sy = read(),n = read();
fo(i,1,n)
{
int xa = read(),ya = read(),xb = read(),yb = read();
if (xa > xb) swap(xa,xb);
if (ya > yb) swap(ya,yb);
sq[i].x = -- xa,sq[i].uy = ++ yb,sq[i].dy = -- ya;
}
sq[++ n].x = sx,sq[n].uy = sq[n].dy = sy,++ n;
sort(sq + 1,sq + n + 1,cmp);
st = 1;
int i = 1;
m = 1;
while (sq[i].x < 0 && sq[i].dy != 0) ++ i;
linking(0,i,1,0);
spfa();
printf("%d\n",dis[fin] + sx);
}