[BZOJ2541][Ctsc2000]冰原探险(bfs)
2016-10-30 13:46
417 查看
题目描述
传送门题解
乍一看这道题好像无从下手,实际上就是预处理之后bfs。因为要冰块要撞上冰山了之后才能停下来,所以从一个地方向某一个方向推它停在哪里是一定的,并且从某一个冰山左右只能忘上下推,从一个冰山的上下只能往左右推。那这样的话,就可以把每一个冰山的四边编上号,然后每一次暴力查找往某个方向推会撞到哪里。将这两个部分连边。那这样的话就会出来一个有向图,用一遍bfs就可以求出最短路。
代码
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define N 100005 #define LL long long const LL inf=1e18; int n,cnt,ans; LL A,B,C,D; int tot,point ,nxt[N*2],v[N*2]; bool vis ; struct hp{LL a,b,c,d;int p[10];}s[4005]; struct hq{int x,step;}; queue <hq> q; int find_up(LL x,LL y) { int ans=0;LL Max=-inf; for (int i=1;i<=n;++i) { LL a=s[i].a,b=s[i].b,c=s[i].c,d=s[i].d; if (c+1<=x&&y>=b&&y<=d&&Max<c+1) { Max=c+1; ans=s[i].p[2]; } } if (y==D&&C<=x&&Max<C) ans=cnt; return ans; } int find_down(LL x,LL y) { int ans=0;LL Min=inf; for (int i=1;i<=n;++i) { LL a=s[i].a,b=s[i].b,c=s[i].c,d=s[i].d; if (a-1>=x&&y>=b&&y<=d&&Min>a-1) { Min=a-1; ans=s[i].p[1]; } } if (y==D&&x<=C&&Min>C) ans=cnt; return ans; } int find_left(LL x,LL y) { int ans=0;LL Max=-inf; for (int i=1;i<=n;++i) { LL a=s[i].a,b=s[i].b,c=s[i].c,d=s[i].d; if (d+1<=y&&x>=a&&x<=c&&Max<d+1) { Max=d+1; ans=s[i].p[4]; } } if (x==C&&D<=y&&Max<D) ans=cnt; return ans; } int find_right(LL x,LL y) { int ans=0;LL Min=inf; for (int i=1;i<=n;++i) { LL a=s[i].a,b=s[i].b,c=s[i].c,d=s[i].d; if (b-1>=y&&x>=a&&x<=c&&Min>b-1) { Min=b-1; ans=s[i].p[3]; } } if (x==C&&D>=y&&Min>D) ans=cnt; return ans; } void add(int x,int y) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; } int bfs() { memset(vis,0,sizeof(vis));vis[1]=true; while (!q.empty()) q.pop(); q.push((hq){1,0}); while (!q.empty()) { hq now=q.front();q.pop(); for (int i=point[now.x];i;i=nxt[i]) { if (v[i]==cnt) return now.step+1; if (!vis[v[i]]) { vis[v[i]]=true; q.push((hq){v[i],now.step+1}); } } } return 0; } int main() { scanf("%d",&n); scanf("%lld%lld%lld%lld",&A,&B,&C,&D); for (int i=1;i<=n;++i) scanf("%lld%lld%lld%lld",&s[i].a,&s[i].b,&s[i].c,&s[i].d); cnt=1; for (int i=1;i<=n;++i) for (int j=1;j<=4;++j) s[i].p[j]=++cnt; ++cnt;int x; x=find_up(A,B); if (x) add(1,x); x=find_down(A,B); if (x) add(1,x); x=find_left(A,B); if (x) add(1,x); x=find_right(A,B); if (x) add(1,x); for (int i=1;i<=n;++i) { LL a=s[i].a,b=s[i].b,c=s[i].c,d=s[i].d; int x; x=find_up(a,b-1); if (x) add(s[i].p[3],x); x=find_up(a,d+1); if (x) add(s[i].p[4],x); x=find_down(c,b-1); if (x) add(s[i].p[3],x); x=find_down(c,d+1); if (x) add(s[i].p[4],x); x=find_left(a-1,b); if (x) add(s[i].p[1],x); x=find_left(c+1,b); if (x) add(s[i].p[2],x); x=find_right(a-1,d); if (x) add(s[i].p[1],x); x=find_right(c+1,d); if (x) add(s[i].p[2],x); } ans=bfs(); printf("%d\n",ans); }
总结
①码力太弱了。相关文章推荐
- 【bzoj 2541】 [Ctsc2000]冰原探险(BFS)
- bzoj 2541: [Ctsc2000]冰原探险 (bfs+建图)
- 【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
- [KM算法] BZOJ 2539 [Ctsc2000]丘比特的烦恼
- bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
- bzoj 2547: [Ctsc2002]玩具兵 bfs&最大匹配
- bzoj2538 [Ctsc2000]公路巡逻
- BZOJ2539: [Ctsc2000]丘比特的烦恼
- [BZOJ2540]ctsc2000快乐的蜜月(dp+归并排序)
- [BZOJ2539][CTSC2000][KM]丘比特的烦恼
- 构图(+BFS)——BZOJ2541/Luogu3716 [CTSC2000]冰原探险
- [BZOJ2539][Ctsc2000]丘比特的烦恼(KM+计算几何)
- 【hdu4844 && bzoj2538】【Ctsc2000】【DP优化】公路巡逻
- BZOJ 2539 [Ctsc2000]丘比特的烦恼 带权二分图的最佳匹配
- 【BZOJ1054】[HAOI2008]移动玩具【BFS】【Hash】
- bzoj 1656: [Usaco2006 Jan] The Grove 树木(BFS)
- BZOJ 2523 [Ctsc2001]聪明的学生
- bzoj1146: [CTSC2008]网络管理Network
- [BZOJ 1146] [CTSC2008]网络管理Network
- 【BZOJ1146】【CTSC2008】网络管理 [整体二分]