poj 2312 soj(中大OJ) 1889

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

      先是poj 2312的代码:

 

  1. #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;
  2. void init()
    {
     int i,j;
     for(i=0;i<m;i++)
      for(j=0;j<n;j++)
       vis[i][j]=0;
    }
  3. bool check(int x,int y)
    {
     if(0<=x && x<m && 0<=y && y<n)
      return true;
     else return false;
    }
  4. bool operator < (point a,point b)
    {
     return b.d<a.d;
    }
  5. 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;
    }
  6. 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的代码:

 

  1. #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;  
     
  2. bool operator < (node a,node b)
    {    
     return b.d<a.d;

     
     
  3. 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;
    }  
     
  4. 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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值