bzoj 2304 [Apio 2011 path]
来源:互联网 发布:杭州软件app 编辑:程序博客网 时间:2024/05/16 08:13
喜闻乐见的最短路。
关于如何求最短路,
关于如何构图,详见《
代码很长,勿喷。。。
感觉
然后居然冲进第一版了。。。
vfk似乎说过这道题代码超过6k的都是弱菜,所以我是大蒟蒻。
#include<map>#include<stack>#include<queue>#include<ctime>#include<cmath>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<utility>#include<iostream>#include<algorithm>const int MAXN = 1005,Nya = -1, SIZE = 2e9+2,INF = 0x3f3f3f3f, NodeNum = MAXN*12;const long long LINF = 1e14;struct Point{int x,y;Point(){}Point(int x,int y):x(x),y(y){}}ptmp;struct Square{int id,xl,xr,yl,yr;Square(){}Square(int id,int xl,int xr,int yl,int yr):id(id),xl(xl),xr(xr),yl(yl),yr(yr){}};struct SqSide{Point up[2],down[2],left[2],right[2];};struct Edge{int v,next;long long w;Edge(){}Edge(int v,long long w,int next):v(v),w(w),next(next){}};bool cmpl(const Square &a,const Square &b){return a.xl < b.xl;}bool cmpr(const Square &a,const Square &b){return a.xr < b.xr;}bool cmpu(const Square &a,const Square &b){return a.yr < b.yr;}bool cmpd(const Square &a,const Square &b){return a.yl < b.yl;}bool cmpi(const Square &a,const Square &b){return a.id < b.id;}bool cmpx(const Point &a,const Point &b){if(a.x!=b.x)return a.x < b.x;else return a.y < b.y;}bool cmpy(const Point &a,const Point &b){if(a.y!=b.y)return a.y < b.y;else return a.x < b.x;}#define Trans(x,y) ((long long)(x)*SIZE+(y))#define Find(x) (std::lower_bound(nd+1,nd+dl+1,(x))-nd)#define Mp(x,y) std::make_pair(x,y)int n;Point S,T;Square ss[MAXN];SqSide sq[MAXN];int sn[MAXN<<1],sl;long long nd[NodeNum];int dl; int head[NodeNum],el;Edge edge[NodeNum<<2];void NewEdge(int u,int v,long long w){ ++el, edge[el] = Edge(v,w,head[u]), head[u] = el;}long long GetDist(const Point &a,const Point &b){ return (long long)abs(a.x-b.x)+abs(a.y-b.y);}namespace osq{ int head[MAXN], el; Point v[NodeNum]; int next[NodeNum]; int blen; Point bowl[NodeNum]; void Clear() { el = 0; memset(head,0,sizeof(head)); memset(next,0,sizeof(next)); memset(v,0,sizeof(v)); } void Add(int u,const Point &val) { ++el, next[el] = head[u], v[el] = val, head[u] = el; } void Solve() { std::sort(ss+1,ss+n+1,cmpi); for(int i = 1; i <= n; i++) { blen = 0; for(int j = head[i]; j ; j = next[j]) bowl[++blen] = v[j]; std::sort(bowl+1,bowl+blen+1,cmpx); for(int k = 1,s1,s2; k < blen; k++) if(bowl[k].x == bowl[k+1].x) if(bowl[k].x == ss[i].xl || bowl[k].x == ss[i].xr) if(bowl[k].y != bowl[k+1].y) { s1 = Find(Trans(bowl[k].x,bowl[k].y)); s2 = Find(Trans(bowl[k+1].x,bowl[k+1].y)); long long dist = GetDist(bowl[k],bowl[k+1]); NewEdge(s1,s2,dist), NewEdge(s2,s1,dist); } std::sort(bowl+1,bowl+blen+1,cmpy); for(int k = 1,s1,s2; k < blen; k++) if(bowl[k].y == bowl[k+1].y) if(bowl[k].y == ss[i].yl || bowl[k].y == ss[i].yr) if(bowl[k].x != bowl[k+1].x) { s1 = Find(Trans(bowl[k].x,bowl[k].y)); s2 = Find(Trans(bowl[k+1].x,bowl[k+1].y)); long long dist = GetDist(bowl[k],bowl[k+1]); NewEdge(s1,s2,dist), NewEdge(s2,s1,dist); } } }}int tree[MAXN<<3],nn;namespace seg{ #define L(x) ((x)<<1) #define R(x) ((x)<<1|1) void PushDown(int x) { if(tree[x] != Nya) { tree[L(x)] = tree[R(x)] = tree[x]; tree[x] = Nya; } } int GetColor(int ll,int rr,int k,int si) { if(ll == rr) return tree[si]; else { int mid = (ll+rr)>>1; PushDown(si); if(k <= mid) return GetColor(ll,mid,k,L(si)); else return GetColor(mid+1,rr,k,R(si)); } } void Color(int ll,int rr,int l,int r,int si,int col) { if(ll == l && rr == r) tree[si] = col; else { int mid = (ll+rr)>>1; PushDown(si); if(r <= mid) Color(ll,mid,l,r,L(si),col); else if(l > mid) Color(mid+1,rr,l,r,R(si),col); else { Color(ll,mid,l,mid,L(si),col); Color(mid+1,rr,mid+1,r,R(si),col); } } }}namespace copy{#define Sfind(x) (std::lower_bound(sn+1,sn+nn+1,(x))-sn)#define Gain(P,E,F) sq[ss[i].id].P = ptmp = Point(E,F), osq::Add(ss[tmp].id,ptmp) void LeftSolve() { tree[1] = sl = 0; std::sort(ss+1,ss+n+1,cmpl); for(int i = 1; i <= n; i++) sn[++sl] = ss[i].yl, sn[++sl] = ss[i].yr; std::sort(sn+1,sn+sl+1); nn = std::unique(sn+1,sn+sl+1)-(sn+1); for(int i = 1,s1,s2,tmp; i <= n; i++) { s1 = Sfind(ss[i].yl); tmp = seg::GetColor(1,nn,s1,1); if(tmp) Gain(left[0],ss[tmp].xr,ss[i].yl); s2 = Sfind(ss[i].yr); tmp = seg::GetColor(1,nn,s2,1); if(tmp) Gain(left[1],ss[tmp].xr,ss[i].yr); seg::Color(1,nn,s1,s2,1,i); } } void RightSolve() { tree[1] = sl = 0; std::sort(ss+1,ss+n+1,cmpr); for(int i = 1; i <= n; i++) sn[++sl] = ss[i].yl, sn[++sl] = ss[i].yr; std::sort(sn+1,sn+sl+1); nn = std::unique(sn+1,sn+sl+1)-(sn+1); for(int i = n,s1,s2,tmp; i >= 1; i--) { s1 = Sfind(ss[i].yl); tmp = seg::GetColor(1,nn,s1,1); if(tmp) Gain(right[0],ss[tmp].xl,ss[i].yl); s2 = Sfind(ss[i].yr); tmp = seg::GetColor(1,nn,s2,1); if(tmp) Gain(right[1],ss[tmp].xl,ss[i].yr); seg::Color(1,nn,s1,s2,1,i); } } void UpSolve() { tree[1] = sl = 0; std::sort(ss+1,ss+n+1,cmpu); for(int i = 1; i <= n; i++) sn[++sl] = ss[i].xl, sn[++sl] = ss[i].xr; std::sort(sn+1,sn+sl+1); nn = std::unique(sn+1,sn+sl+1)-(sn+1); for(int i = n,s1,s2,tmp; i >= 1; i--) { s1 = Sfind(ss[i].xl); tmp = seg::GetColor(1,nn,s1,1); if(tmp) Gain(up[0],ss[i].xl,ss[tmp].yl); s2 = Sfind(ss[i].xr); tmp = seg::GetColor(1,nn,s2,1); if(tmp) Gain(up[1] ,ss[i].xr,ss[tmp].yl); seg::Color(1,nn,s1,s2,1,i); } } void DownSolve() { tree[1] = sl = 0; std::sort(ss+1,ss+n+1,cmpu); for(int i = 1; i <= n; i++) sn[++sl] = ss[i].xl, sn[++sl] = ss[i].xr; std::sort(sn+1,sn+sl+1); nn = std::unique(sn+1,sn+sl+1)-(sn+1); for(int i = 1,s1,s2,tmp; i <= n; i++) { s1 = Sfind(ss[i].xl); tmp = seg::GetColor(1,nn,s1,1); if(tmp) Gain(down[0] ,ss[i].xl,ss[tmp].yr); s2 = Sfind(ss[i].xr); tmp = seg::GetColor(1,nn,s2,1); if(tmp) Gain(down[1] ,ss[i].xr,ss[tmp].yr); seg::Color(1,nn,s1,s2,1,i); } }}#define Insert(g) if(g[0].x != INF) nd[++dl] = Trans(g[0].x,g[0].y);\ if(g[1].x != INF) nd[++dl] = Trans(g[1].x,g[1].y);void GetAllNode(){ std::sort(ss+1,ss+n+1,cmpi); for(int i = 1; i <= n; i++) { Insert(sq[i].up); Insert(sq[i].down); Insert(sq[i].left); Insert(sq[i].right); nd[++dl] = Trans(ss[i].xl,ss[i].yl), nd[++dl] = Trans(ss[i].xl,ss[i].yr), nd[++dl] = Trans(ss[i].xr,ss[i].yl), nd[++dl] = Trans(ss[i].xr,ss[i].yr); } std::sort(nd+1,nd+dl+1); dl = std::unique(nd+1,nd+dl+1)-(nd+1);}#define Connect(g) \ if(g.x != INF) \ { \ s2 = Find(Trans(g.x,g.y)); \ dist = GetDist(ptmp,g); \ NewEdge(s1,s2,dist),NewEdge(s2,s1,dist); \ }void BuildGraph(){ std::sort(ss+1,ss+n+1,cmpi); for(int i = 1,s1,s2; i <= n; i++) { long long dist; ptmp = Point(ss[i].xl,ss[i].yr); s1 = Find(Trans(ss[i].xl,ss[i].yr)); Connect(sq[i].up[0]); Connect(sq[i].left[1]); ptmp = Point(ss[i].xr,ss[i].yl); s1 = Find(Trans(ss[i].xr,ss[i].yl)); Connect(sq[i].down[1]); Connect(sq[i].right[0]); ptmp = Point(ss[i].xl,ss[i].yl); s1 = Find(Trans(ss[i].xl,ss[i].yl)); Connect(sq[i].down[0]); Connect(sq[i].left[0]); ptmp = Point(ss[i].xr,ss[i].yr); s1 = Find(Trans(ss[i].xr,ss[i].yr)); Connect(sq[i].up[1]); Connect(sq[i].right[1]); } for(int i = 1; i <= n; i++) { ptmp = Point(ss[i].xl,ss[i].yl),osq::Add(ss[i].id,ptmp); ptmp = Point(ss[i].xr,ss[i].yl),osq::Add(ss[i].id,ptmp); ptmp = Point(ss[i].xl,ss[i].yr),osq::Add(ss[i].id,ptmp); ptmp = Point(ss[i].xr,ss[i].yr),osq::Add(ss[i].id,ptmp); } osq::Solve();}typedef std::pair<long long,int> HeapNode;std::priority_queue<HeapNode,std::vector<HeapNode>,std::greater<HeapNode> > heap;bool flag[NodeNum];#define num secondlong long Dijstra(int s,int t){ static long long dist[NodeNum]; memset(flag,false,sizeof(flag)); for(int i = 1; i <= dl; i++) dist[i] = LINF; dist[s] = 0; heap.push(Mp(0,s)); while(!heap.empty()) { int x = heap.top().num; heap.pop(); if(flag[x])continue; flag[x] = true; for(int i = head[x]; i ; i = edge[i].next) { int p = edge[i].v;long long tmp = dist[x] + edge[i].w; if(tmp < dist[p]) dist[p] = tmp, heap.push(Mp(dist[p],p)); } } return dist[t];}void Solve(){ copy::UpSolve(); copy::DownSolve(); copy::LeftSolve(); copy::RightSolve(); GetAllNode(); BuildGraph(); int st = Find(Trans(S.x,S.y)),ed = Find(Trans(T.x,T.y)); long long ans = Dijstra(st,ed); if(ans < LINF) printf("%lld\n",ans); else puts("No Path"); }void Clear(){ dl = el = 0; memset(sq,0x3f3f3f3f,sizeof(sq)); memset(head,0,sizeof(head)); osq::Clear();}void Init(){ scanf("%d%d%d%d",&S.x,&S.y,&T.x,&T.y); scanf("%d",&n); for(int i = 1,x1,y1,x2,y2; i <= n; i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1 > x2) std::swap(x1,x2); if(y1 > y2) std::swap(y1,y2); ss[i] = Square(i,x1,x2,y1,y2); } ss[n+1] = Square(n+1,S.x,S.x,S.y,S.y); ss[n+2] = Square(n+2,T.x,T.x,T.y,T.y); n += 2;}int main(){ int Case;#ifndef ONLINE_JUDGE freopen("path.in","r",stdin); freopen("path.out","w",stdout);#endif scanf("%d",&Case); while(Case--) { Clear(); Init(); Solve(); }#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif}
0 0
- bzoj 2304 [Apio 2011 path]
- [BZOJ 1913][APIO 2011]信号覆盖(计算几何)
- [BZOJ 1179][APIO 2009]Atm
- BZOJ 2809 (APIO 2012) 左偏树
- BZOJ 1178 APIO 2009 会议中心
- 【BZOJ 4584】【APIO 2016】赛艇
- BZOJ 1179 APIO 2009 Atm Tarjan+SPFA
- [BZOJ 3676][APIO 2014]回文串
- BZOJ 1913 [Apio]signaling 信号覆盖 方法简析
- BZOJ 2809 APIO 2012 dispatching 平衡树启发式合并
- BZOJ 1911 APIO 2010 特别行动队 斜率优化DP
- [BZOJ 1912][APIO 2010]patrol 巡逻(树的直径)
- [BZOJ 3675][APIO 2014]序列分割(斜率优化DP)
- BZOJ 3676 UOJ 103 APIO 2014 后缀自动机 Manacher
- [省选前题目整理][BZOJ 1911][APIO 2010]特别行动队(斜率优化DP)
- [省选前题目整理][BZOJ 3675][APIO 2014]序列分割(斜率优化DP)
- 【并查集】【生成树】【APIO 2008】【bzoj 3624】免费道路
- [CTSC && APIO]
- 【ThinkingInJava】18、 关于java中的闭包与回调
- bootstrap 之 基本知识
- SOLR使用手册之操作collection
- POJ 2763 Housewife Wind (树链剖分)
- UI篇 -- 自定义view
- bzoj 2304 [Apio 2011 path]
- Android客户端与Java tomcat之间HTTPS通讯
- bootstrap 之准备开发
- swift语言-变量和常量基本知识
- bootstrap 之 CSS样式
- 求数根
- 推荐!国外程序员整理的机器学习资源大全
- 重载与多态性
- 祥总教我的快速跳转到文件另一方法