[BZOJ1644][Usaco2007 Oct]Obstacle Course 障碍训练课(spfa)
来源:互联网 发布:网络没有上传速度 编辑:程序博客网 时间:2024/05/18 09:03
题目描述
传送门
题解
看题之后一上手写了个dfs,结果发现tle了?
分析一下dfs的复杂度:如果不考虑最优化剪枝的话,是搜到终点再返回的。那么在最坏情况下,每个点的访问次数是指数级别的。
这不T就鬼了啊
改成spfa之后就A了。由于每一个点从四个方向走过来时的方案有可能是不同的,所以f(i,j,k)表示到(i,j)这个点,是从方向k走过来的最优值。也就相当于把一个点拆成了4个来做。
spfa的复杂度是
代码
dfs(tle)
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 105#define inf 2000000000int n,sx,sy,tx,ty,ans;char a[N][N],s[N];int f[N][N][5];int dx[5]={0,0,0,1,-1};int dy[5]={0,1,-1,0,0};void dfs(int x,int y,int dep,int dir){ if (dep>=f[x][y][dir]||dep>=ans) return; f[x][y][dir]=dep; if (x==tx&&y==ty) { ans=min(ans,dep); return; } for (int i=1;i<=4;++i) { int nx=x+dx[i],ny=y+dy[i]; if (nx<1||nx>n||ny<1||ny>n||a[nx][ny]=='x') continue; if (!dir||dir==i) dfs(nx,ny,dep,i); else dfs(nx,ny,dep+1,i); }}int main(){ scanf("%d\n",&n); for (int i=1;i<=n;++i) { gets(s); for (int j=1;j<=n;++j) { a[i][j]=s[j-1]; if (s[j-1]=='A') sx=i,sy=j; if (s[j-1]=='B') tx=i,ty=j; } } ans=inf; memset(f,127,sizeof(f)); f[sx][sy][1]=f[sx][sy][2]=f[sx][sy][3]=f[sx][sy][4]=0; dfs(sx,sy,0,0); printf("%d\n",ans);}
spfa
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define N 105int n,sx,sy,tx,ty,ans;char a[N][N],s[N];int f[N][N][4];bool vis[N][N][4];int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};struct hp{int x,y,dir;};queue <hp> q;int Min(int a,int b,int c,int d){ if (a>b) a=b; if (a>c) a=c; if (a>d) a=d; return a;}int main(){ scanf("%d\n",&n); for (int i=1;i<=n;++i) { gets(s); for (int j=1;j<=n;++j) { a[i][j]=s[j-1]; if (s[j-1]=='A') sx=i,sy=j; if (s[j-1]=='B') tx=i,ty=j; } } memset(f,127,sizeof(f)); f[sx][sy][0]=f[sx][sy][1]=f[sx][sy][2]=f[sx][sy][3]=0; vis[sx][sy][0]=vis[sx][sy][1]=vis[sx][sy][2]=vis[sx][sy][3]=true; q.push((hp){sx,sy,0});q.push((hp){sx,sy,1});q.push((hp){sx,sy,2});q.push((hp){sx,sy,3}); while (!q.empty()) { hp now=q.front();q.pop(); vis[now.x][now.y][now.dir]=false; for (int i=0;i<4;++i) { int x=now.x+dx[i],y=now.y+dy[i]; if (x<1||x>n||y<1||y>n||a[x][y]=='x') continue; int len; if (i==now.dir) len=0; else len=1; if (f[x][y][i]>f[now.x][now.y][now.dir]+len) { f[x][y][i]=f[now.x][now.y][now.dir]+len; if (!vis[x][y][i]) vis[x][y][i]=true,q.push((hp){x,y,i}); } } } ans=Min(f[tx][ty][0],f[tx][ty][1],f[tx][ty][2],f[tx][ty][3]); printf("%d\n",ans);}
总结
①永远不要忘记分析时间复杂度。
0 0
- [BZOJ1644][Usaco2007 Oct]Obstacle Course 障碍训练课(spfa)
- bzoj1644 [Usaco2007 Oct]Obstacle Course 障碍训练课
- bzoj1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
- 【bzoj1644】 [Usaco2007 Oct]Obstacle Course 障碍训练课
- BZOJ 1644 Usaco2007 Oct Obstacle Course 障碍训练课 SPFA
- [BZOJ1644][Usaco2007Oct]Obstacle Course 障碍训练课(spfa)
- bzoj 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 (spfa)
- BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
- bzoj 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课(BFS)
- bzoj 1644: Obstacle Course 障碍训练课 BFS
- [USACO07OCT] 障碍路线Obstacle Course
- poj2374 Fence Obstacle Course(线段树+建图spfa)
- Obstacle Course(优先队列+BFS)
- pku2374 Fence Obstacle Course
- poj2374 Fence Obstacle Course
- sicily1703. Obstacle Course
- Sicily 1703. Obstacle Course
- HDU 3152 Obstacle Course
- java中多态
- 1068. Find More Coins (30)解题报告
- iOS Cocoa Touch Framework 学习(1)
- minigui3.0.12之初体验-移植篇
- 代码整洁之道笔记(一)
- [BZOJ1644][Usaco2007 Oct]Obstacle Course 障碍训练课(spfa)
- java中的单例模式
- hdu_1251 统计难题(字典树)
- 一脸懵逼的Socket-http对比
- 关于strcpy的面试题
- java验证码
- NIO的工作方式(一)
- nutch2.2.1安装部署
- 【PAT甲级】1064. Complete Binary Search Tree (30)