首页 > 代码库 > 四校联考 推冰块
四校联考 推冰块
2<=n,m<=10^9,0<=k<=50000。
我们发现有用的格子不是很多,经过详细的分类讨论,只有这些格子是有用的:
四个角,以及障碍物(或减速带)本身和上下左右四个方向,以及障碍物所在行列(及±1的)的头尾两个。
那么我们只要把所有 障碍 和 减速带 按x-y和y-x排序一下,对于每一个有用的格子二分一下找到往左和往右会推到哪里,连边完暴力bfs即可。
#include <iostream>#include <stdio.h>#include <math.h>#include <string.h>#include <time.h>#include <stdlib.h>#include <string>#include <bitset>#include <vector>#include <set>#include <map>#include <queue>#include <algorithm>#include <sstream>#include <stack>#include <iomanip>using namespace std;#define pb push_back#define mp make_pairtypedef pair<int,int> pii;typedef long long ll;typedef double ld;typedef vector<int> vi;#define fi first#define se second#define fe first#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}#define es(x,e) (int e=fst[x];e;e=nxt[e])#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}#ifdef LOCAL#define TIMER cerr<<clock()<<"ms\n"#else#define TIMER#endif#define SZ 1234567int n,m,k,N=0;int xs[SZ],ys[SZ],ts[SZ];typedef pair<int,int> pii;map<pii,int> sta;bool cmp2(pii a,pii b){ if(a.se!=b.se) return a.se<b.se; return a.fi<b.fi;}pii ps[SZ]; int pn=0;pii ss[SZ],rs[SZ];int dx[4]={1,-1,0,0},dy[4]={0,0,-1,1};void rec(int a,int b){ if(sta[pii(a,b)]==1) return; if(a<1||b<1||a>n||b>m) return; ps[++pn]=pii(a,b);}int ls(pii a) {return lower_bound(ps+1,ps+1+pn,a)-ps;}int S,T;int qs[SZ];int dist[SZ];#undef SZ#define SZ 1234567Edgvoid conn(pii a,pii b){ if(a==b) return; ad_de(ls(a),ls(b));}void spfa(){ int h=0,t=0; qs[t++]=S; dist[S]=1; while(h^t) { int x=qs[h++]; for es(x,e) { int b=vb[e]; if(dist[b]) continue; dist[b]=dist[x]+1; qs[t++]=b; } }}int main(){ FO(ice) scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++) { scanf("%d%d%d",xs+i,ys+i,ts+i); sta[pii(xs[i],ys[i])]=ts[i]+1; } rec(1,1); rec(n,m); rec(1,m); rec(n,1); for(int i=1;i<=k;i++) { rec(xs[i],1); rec(xs[i],m); rec(1,ys[i]); rec(n,ys[i]); rec(xs[i]+1,1); rec(xs[i]+1,m); rec(xs[i]-1,1); rec(xs[i]-1,m); rec(1,ys[i]+1); rec(n,ys[i]+1); rec(1,ys[i]-1); rec(n,ys[i]-1); rec(xs[i],ys[i]); for(int j=0;j<4;j++) rec(xs[i]+dx[j],ys[i]+dy[j]); } sort(ps+1,ps+1+pn); pn=unique(ps+1,ps+1+pn)-ps-1; int sn=0,rn=0; for(int i=1;i<=k;i++) { if(ts[i]==0) ss[++sn]=pii(xs[i],ys[i]); else rs[++rn]=pii(xs[i],ys[i]); } ss[++sn]=pii(-2000000000,-2000000000); ss[++sn]=pii(2000000000,2000000000); rs[++rn]=pii(-2000000000,-2000000000); rs[++rn]=pii(2000000000,2000000000); sort(ss+1,ss+1+sn); sort(rs+1,rs+1+rn); //先处理左右 for(int i=1;i<=pn;i++) { int x=ps[i].fi,y=ps[i].se; pii cur=pii(x,y); if(y!=1) //L { int maxn=1; int id=lower_bound(rs+1,rs+1+rn,cur)-rs-1; pii ns=rs[id]; if(ns.fi==x) maxn=max(maxn,ns.se); id=lower_bound(ss+1,ss+1+sn,cur)-ss-1; ns=ss[id]; if(ns.fi==x) maxn=max(maxn,ns.se+1); conn(cur,pii(x,maxn)); } if(y!=m) //R { int minn=m; int id=upper_bound(rs+1,rs+1+rn,cur)-rs; pii ns=rs[id]; if(ns.fi==x) minn=min(minn,ns.se); id=upper_bound(ss+1,ss+1+sn,cur)-ss; ns=ss[id]; if(ns.fi==x) minn=min(minn,ns.se-1); conn(cur,pii(x,minn)); } } sort(ss+1,ss+1+sn,cmp2); sort(rs+1,rs+1+rn,cmp2); for(int i=1;i<=pn;i++) { int x=ps[i].fi,y=ps[i].se; pii cur=pii(x,y); if(x!=1) //U { int maxn=1; int id=lower_bound(rs+1,rs+1+rn,cur,cmp2)-rs-1; pii ns=rs[id]; if(ns.se==y) maxn=max(maxn,ns.fi); id=lower_bound(ss+1,ss+1+sn,cur,cmp2)-ss-1; ns=ss[id]; if(ns.se==y) maxn=max(maxn,ns.fi+1); conn(cur,pii(maxn,y)); } if(x!=n) //R { int minn=n; int id=upper_bound(rs+1,rs+1+rn,cur,cmp2)-rs; pii ns=rs[id]; if(ns.se==y) minn=min(minn,ns.fi); id=upper_bound(ss+1,ss+1+sn,cur,cmp2)-ss; ns=ss[id]; if(ns.se==y) minn=min(minn,ns.fi-1); conn(cur,pii(minn,y)); } } S=ls(pii(1,1));T=ls(pii(n,m)); spfa(); cout<<dist[T]-1<<"\n";}
四校联考 推冰块
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。