POJ 2049 Finding Nemo 网格bfs

题目连接:http://poj.org/problem?id=2049

第一次遇到这种网格bfs。因为是迷宫问题所以一开始就认为是bfs或者是最短路。然后发现不知道网格应该怎么处理,后来想用网格的一个点来代替这个网格,但是有四条边。后来一想其实可以认为每个网格只有两条边,右边和上边。这样可以用右上方的点代表一个网格,然后用一个三维map[2][i][j]来表示,0,1分别表示恨着和竖着,然后用类似最短路的一个数组来记录门数,当其sx和sy超过199小于0直接输出0;

一开始拉了一个if一直re= =...

代码:

View Code
  1 #include <stdio.h>
  2 #include <string.h>
  3 #define N 256
  4 #define max 20000000
  5 int map[2][N][N],to[4][2] = {-1,0,1,0,0,-1,0,1};
  6 struct node
  7 {
  8     int x,y;
  9 }q[N*N];
 10 int f,r;
 11 
 12 int judge(int x,int y,int maxx,int maxy)
 13 {
 14     if(x>0 && x <= maxx && y > 0 && y <= maxy)
 15     return 1;
 16 
 17     return 0;
 18 }
 19 int value(int x,int y,int i)
 20 {
 21     if(i == 0)
 22     return map[1][x-1][y];
 23     if(i == 1)
 24     return map[1][x][y];
 25     if(i == 2)
 26     return map[0][x][y-1];
 27     return map[0][x][y];
 28 }
 29 int bfs(int sx,int sy,int maxx,int maxy)
 30 {
 31     int dis[N][N];
 32     int i,j;
 33     for(i = 1;i <= maxy;i++)
 34     for(j = 1;j <= maxx;j++)
 35     dis[i][j] = max;
 36 
 37     dis[1][1] = 0;
 38 
 39     f = r = 0;
 40     q[r].x = q[r].y = 1;
 41     r++;
 42 
 43     while(f < r)
 44     {
 45         struct node temp,now;
 46         temp = q[f++];
 47 
 48         for(i = 0;i < 4;i++)
 49         {
 50             now.x = temp.x+to[i][0];
 51             now.y = temp.y+to[i][1];
 52 
 53             if(judge(now.x,now.y,maxx,maxy) && dis[now.x][now.y] > dis[temp.x][temp.y] + value(temp.x,temp.y,i))
 54             {
 55                 dis[now.x][now.y] = dis[temp.x][temp.y] + value(temp.x,temp.y,i);
 56                 q[r] = now;
 57                 r++;
 58             }
 59         }
 60     }
 61     if(dis[sx][sy] != max)
 62     return dis[sx][sy];
 63     return -1;
 64 }
 65 int main()
 66 {
 67     int m,n,maxy,maxx;
 68     int x,y,t,d;
 69 
 70     while(~scanf("%d %d",&m,&n))
 71     {
 72         if(m == n && n== -1)
 73         break;
 74 
 75         maxy = maxx = -1;
 76         memset(map,0,sizeof(map));
 77 
 78         while(m--)
 79         {
 80             scanf("%d %d %d %d",&x,&y,&d,&t);
 81             if(d)
 82             {
 83                 int i;
 84                 for(i = 0;i < t;i++)
 85                 map[d][x][y+i+1] = max;
 86 
 87                 if(maxy < y+1+t)
 88                 maxy = y+1+t;
 89                 if(maxx < x+1)
 90                 maxx = x+1;
 91             }
 92             else
 93             {
 94                 int i;
 95                 for(i = 0;i < t;i++)
 96                 map[d][x+i+1][y] = max;
 97 
 98                 if(maxx < x+t+1)
 99                 maxx = x+t+1;
100                 if(maxy < y+1)
101                 maxy = y+1;
102             }
103         }
104         while(n--)
105         {
106             scanf("%d %d %d",&x,&y,&d);
107             if(d)
108             map[d][x][y+1] = 1;
109             else
110             map[d][x+1][y] = 1;
111         }
112         double sx,sy;
113         scanf("%lf %lf",&sx,&sy);
114         if(!(sx>=1 && sx<=199 && sy>=1 && sy<=199)) printf("0\n");
115         else printf("%d\n",bfs((int)sx+1,(int)sy+1,maxx,maxy));
116     }
117     return 0;
118 }

 


  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #define max 0x5fffffff
  5 using namespace std;
  6 int map[205][205];
  7 struct node
  8 {
  9     int val;
 10     int lev;
 11     int n;
 12 }a[205];//主要用来存放物品的等级
 13 void inint(int n)
 14 {
 15     int i,j;
 16     for(i = 1;i <= n;i++)
 17     {
 18         for(j = 1;j <= n;j++)
 19         map[i][j] = max;
 20         map[i][i] = 0;
 21     }
 22     return;
 23 }
 24 int is_leagle(int i,int minl,int maxl)
 25 {
 26     if(a[i].lev > maxl|| minl > a[i].lev)
 27     return 0;
 28 
 29     return 1;
 30 }
 31 int dijks(int n,int s,int m)
 32  {
 33      int vis[205] = {0},val[205];
 34      int k,i,min,j,pre,maxl,minl;
 35 
 36 
 37      
 38      int ans = a[1].val;
 39      for(k = 0;k <= m;k++)
 40      {
 41          memset(vis,0,sizeof(vis));
 42          for(i = 1;i <= n;i++)
 43             val[i] = map[s][i];//val存放的就是从1到i的值
 44         pre = s;
 45         vis[pre] = 1;
 46          maxl = a[1].lev+m-k;
 47          minl = a[1].lev-k;
 48         for(i = 1;i <= n;i++)
 49         {
 50              if(!is_leagle(i,minl,maxl))//去除不能用的点
 51              vis[i] = 1;
 52          }
 53          min = max;
 54 
 55          for(i = 1;i < n;i++)
 56          {
 57              min = max;
 58              for(j = 1;j <= n;j++)
 59              {
 60                  if(!vis[j] && val[j] > map[pre][j]+val[pre] && map[pre][j] <max )
 61                  val[j] = val[pre]+map[pre][j];
 62              }
 63 
 64              for(j = 1;j <= n;j++)
 65              {
 66 
 67                  if(min > val[j] && !vis[j])
 68                  min = val[j],pre = j;
 69              }
 70 
 71              vis[pre] = 1;
 72          }
 73 
 74 
 75          int minval;
 76          minval = a[1].val;//初始化为a[i]。val
 77          for(i = 1;i <= n;i++)
 78          {
 79              if(val[i]+a[i].val < minval && is_leagle(i,minl,maxl))//寻找这个等级范围的最小值
 80              minval = val[i]+a[i].val;
 81          }
 82          if(ans > minval)//看看ans是否会更改
 83          ans = minval;
 84      }
 85 
 86      return ans;
 87  }
 88 
 89 int main()
 90 {
 91     int m,n,i,j;
 92     while(scanf("%d %d",&m,&n)!= EOF)
 93     {
 94 
 95     inint(n);
 96     for(i = 1;i <= n;i++)
 97     {
 98         scanf("%d %d %d",&a[i].val,&a[i].lev,&a[i].n);
 99         for(j = 0;j < a[i].n;j++)
100         {
101             int num,val;
102             scanf("%d %d",&num,&val);
103             map[i][num] = val;//建图
104         }
105     }
106 
107 
108 
109 
110 
111     printf("%d\n",dijks(n,1,m));
112     }
113     return 0;
114 }
posted @ 2012-11-01 02:08  某某。  阅读(353)  评论(0编辑  收藏  举报