您的位置:首页 > 其它

poj 2312 soj(中大OJ) 1889

2011-05-17 12:43 190 查看
这两类题目的共同解法都是用bfs+heap。求起点到终点的距离使用bfs+判重即可,但转移到不同的地区所要走的距离会变化时,一般的bfs很难有最优解甚至tle。因此,我们可以把每次从当前起点出发所到的地方的距离记录下来放入heap中,同时由于在bfs中每个地方所到的第一次距离是最短距离,因此每个地方不必进入两次,这里做好判重。

先是poj 2312的代码:

#include<cstdio>
#include<queue>
using namespace std;
const int M=320;
const int inf=20;
struct point
{
int x,y;
int d;
}s;
char map[M][M];
bool vis[M][M];
int dir[4][2]={-1,0,1,0,0,-1,0,1};
int m,n;

void init()
{
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
vis[i][j]=0;
}

bool check(int x,int y)
{
if(0<=x && x<m && 0<=y && y<n)
return true;
else return false;
}

bool operator < (point a,point b)
{
return b.d<a.d;
}

int solve()
{
int i,j;
priority_queue<point> Q;
vis[s.x][s.y]=1;
s.d=1;
Q.push(s);
while(!Q.empty())
{
point p=Q.top(),q;
Q.pop();
for(i=0;i<4;i++)
{
q.x=p.x+dir[i][0];
q.y=p.y+dir[i][1];
if(!check(q.x,q.y)) continue;
if(map[q.x][q.y]=='R' || map[q.x][q.y]=='S') continue;
else if(map[q.x][q.y]=='E')
{
if(!vis[q.x][q.y])
{
q.d=p.d+1;
vis[q.x][q.y]=1;
Q.push(q);
}
}
else if(map[q.x][q.y]=='B')
{
if(!vis[q.x][q.y])
{
q.d=p.d+2;
vis[q.x][q.y]=1;
Q.push(q);
}
}
else if(map[q.x][q.y]=='T')
{
q.d=p.d;
return q.d;
}
}
}
return -1;
}

int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d",&m,&n)==2)
{
if(!m && !n) break;
init();
int i,j;
for(i=0;i<m;i++)
scanf("%s",map[i]);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
if(map[i][j]=='Y')
{
s.x=i;
s.y=j;
vis[i][j]=1;
break;
}
int ans=solve();
printf("%d/n",ans);
}
return 0;
}

接下来是soj 1889的代码:

#include "cstdio"
#include "cstring"
#include "queue"
using namespace std;
const int M=600;
struct node
{
int x,y,d;
}star,end;
char map[M][M];
bool vis[M][M];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int n,m;

bool operator < (node a,node b)
{
return b.d<a.d;
}

int bfs()
{
priority_queue<node> Q;
int i;
node p,q;
Q.push(star);
vis[star.x][star.y]=1;
star.d=0;
while(!Q.empty())
{
p=Q.top();
Q.pop();
for(i=0;i<4;i++)
{
q.x=p.x+dir[i][0];
q.y=p.y+dir[i][1];
if(q.x>=0 && q.x<n && q.y>=0 && q.y<m && !vis[q.x][q.y])
{
q.d=p.d+(map[p.x][p.y]!=map[q.x][q.y]);
if(q.x==end.x && q.y==end.y) return q.d;
Q.push(q);
vis[q.x][q.y]=1;
}
}
}
return 0;
}

int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==2)
{
int i;
memset(vis,false,sizeof(vis));
for(i=0;i<n;i++)
scanf("%s",map[i]);
scanf("%d%d%d%d",&star.x,&star.y,&end.x,&end.y);
printf("%d/n",bfs());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: