{题解}[jzoj5049]【GDOI2017模拟一试4.11】腐女的生日

来源:互联网 发布:python求最大公约数包 编辑:程序博客网 时间:2024/05/04 18:18

按照惯例

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);}
1 0
原创粉丝点击