构图(+BFS)——BZOJ2541/Luogu3716 [CTSC2000]冰原探险
来源:互联网 发布:网络传播正能量的例子 编辑:程序博客网 时间:2024/04/29 21:25
题面:Luogu3716 BZOJ2541
无限烧脑预处理建图系列,同时也是我攻下的CTSC第一题!
只要把图能建得出来就Accepted了
所以只说建图(最后的bfs有什么好说的。。。)
我们把冰山拆成四个点,冰山的每一边是一个点
然后我们暴力对每一个点(也就是冰山的边)往上下左右找最近的能撞的冰山(或者直接掉进洞里),然后连上有向边(注意有向边!!!)
当然啦,每一条边要么上下方向要么左右方向
起点再特殊处理一下好了
但是呢你建的时候还有很多要处理的东西
比如几个坑点:
- 洞必须要特判!(下面会说)
- 数据中坐标可能是负数(数据里好像有)
- 数据中坐标可能爆int(这个我不太确定但是可能吧)
- (以上两点是针对于题中未给坐标范围所致)
- 选择上下左右建图时必须要滑过整块冰山的边(因为有可能洞在冰山的边上如果直接滑出去就会忽略洞导致输出0)
- 对于上一点具体意思就是说往上下左右找的时候要从这条边的起始点出发而不是终点
- 还有撞到冰山坐标还要减1或加1(这个好像忽略应该也没关系,
我也不知道),然而洞就不需要
最后跑bfs,完结,撒花!
献上原来压到只剩70行的100行代码(码力啊码力)
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<cstdlib>#include<set>#include<map>#include<string>#include<ctime>#include<queue>#include<vector>using namespace std;typedef long long ll;bool vis[100001];struct ppap{ll xx,xy,dx,dy;}a[100001];int dist[100001],bh[5001][5];int nedge=0,p[100001],nex[100001],head[100001];int n,s=1,cnt=1,t;ll sx,sy,tx,ty;inline void addedge(int a,int b){p[++nedge]=b;nex[nedge]=head[a];head[a]=nedge;}inline void add(int x,int y,int z){if(y<t)addedge(x,bh[y][z]);else addedge(x,t);}inline int down(ll x,ll y){ int fh=0;ll min=1e18; for(int i=1;i<=n;i++) if(y>=a[i].xy&&y<=a[i].dy&&x<=a[i].xx-1&&min>a[i].xx-1) min=a[i].xx-1,fh=i; if(y==ty&&x<=tx&&min>tx)return t; return fh;}inline int left(ll x,ll y){ int fh=0;ll max=-1e18; for(int i=1;i<=n;i++) if(x>=a[i].xx&&x<=a[i].dx&&y>=a[i].dy+1&&max<a[i].dy+1) max=a[i].dy+1,fh=i; if(x==tx&&y>=ty&&max<ty)return t; return fh;}inline int up(ll x,ll y){ int fh=0;ll max=-1e18; for(int i=1;i<=n;i++) if(y>=a[i].xy&&y<=a[i].dy&&x>=a[i].dx+1&&max<a[i].dx+1) max=a[i].dx+1,fh=i; if(y==ty&&x>=tx&&max<tx)return t; return fh;}inline int right(ll x,ll y){ int fh=0;ll min=1e18; for(int i=1;i<=n;i++) if(x>=a[i].xx&&x<=a[i].dx&&y<=a[i].xy-1&&min>a[i].xy-1) min=a[i].xy-1,fh=i; if(x==tx&&y<=ty&&min>ty)return t; return fh;}inline void bfs(int x){ dist[t]=1e9;dist[x]=0;queue<int>q;q.push(x);vis[x]=1; while(!q.empty()){ int now=q.front();q.pop(); for(int k=head[now];k;k=nex[k])if(!vis[p[k]]){ dist[p[k]]=dist[now]+1; if(p[k]==t)return;vis[p[k]]=1; q.push(p[k]); } }}int main(){ scanf("%d%lld%lld%lld%lld",&n,&sx,&sy,&tx,&ty); for(int i=1;i<=n;i++) scanf("%lld%lld%lld%lld",&a[i].xx,&a[i].xy,&a[i].dx,&a[i].dy); for(int i=1;i<=n;i++) for(int j=1;j<5;j++)bh[i][j]=++cnt;t=++cnt; if(cnt=down(sx,sy)) add(s,cnt,1); if(cnt=left(sx,sy)) add(s,cnt,2); if(cnt=up(sx,sy)) add(s,cnt,3); if(cnt=right(sx,sy)) add(s,cnt,4); for(int i=1;i<=n;i++){ if(cnt=down(a[i].xx,a[i].dy+1)) add(bh[i][2],cnt,1); if(cnt=down(a[i].xx,a[i].xy-1)) add(bh[i][4],cnt,1); if(cnt=left(a[i].xx-1,a[i].dy)) add(bh[i][1],cnt,2); if(cnt=left(a[i].dx+1,a[i].dy)) add(bh[i][3],cnt,2); if(cnt=up(a[i].dx,a[i].dy+1)) add(bh[i][2],cnt,3); if(cnt=up(a[i].dx,a[i].xy-1)) add(bh[i][4],cnt,3); if(cnt=right(a[i].xx-1,a[i].xy)) add(bh[i][1],cnt,4); if(cnt=right(a[i].dx+1,a[i].xy)) add(bh[i][3],cnt,4); } bfs(1); if(dist[t]!=1e9)printf("%d",dist[t]); else puts("0"); return 0;}
阅读全文
1 0
- 构图(+BFS)——BZOJ2541/Luogu3716 [CTSC2000]冰原探险
- [BZOJ2541][Ctsc2000]冰原探险(bfs)
- 【bzoj 2541】 [Ctsc2000]冰原探险(BFS)
- bzoj 2541: [Ctsc2000]冰原探险 (bfs+建图)
- CTSC2000 冰原探险
- 宝岛探险1(BFS)
- tianchai 12035 宝岛探险 (BFS)
- 数据结构探险—栈篇
- 宝岛探险 BFS DFS
- 数据结构探险——栈篇
- 数据结构探险——树篇
- 数据结构探险——图篇
- JDK8探险——CompletableFuture
- 构图之法——9条构图小贴士
- 啊哈报道探险(基础bfs)
- DFS/BFS解决宝岛探险
- SpringMVC深度探险(一) —— SpringMVC前传
- SpringMVC深度探险(二) —— SpringMVC概览
- 用Nodejs连接MySQL
- if..else使用陷阱
- iOS项目运行注意事项
- java EE的三层结构:web层、service层、dao层
- 将读入的多维list转为一维list的方法(python)
- 构图(+BFS)——BZOJ2541/Luogu3716 [CTSC2000]冰原探险
- git的安装与AndroidStudio关联GitHub
- Android 4.4 Graphic系统详解(2) VSYNC的生成
- iPad + iOS!iOS 11 将大大改进 iPad 的工作能力
- 浅谈--java线程池
- Android:OpenCV学习日记(一)-- 环境搭建
- xcode9 新功能
- 限时免费 | 用正确的方式,三天搞定Mono堆内存泄漏!
- launchMode使用详解