zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    EXCEL中用VLOOKUP功能,根据A列的值,把B列也填充上对应的值
    ReNamer批量重命名文件,如何给杂乱无章的文件名重新命名
    小米手机亲情守护(风筝守护)怎么解绑?
    PHP正则表达式遇到的一个utf8乱码坑
    筹米网你用过没?是套路还是真能帮你提前抢购域名?
    CSS选取第一个、最后一个、偶数、奇数、第n个标签元素
    winscp会话超时及尝试关闭优化连接缓冲大小
    Linux下压缩和解压
    一步一步学Linux下vi/vim的使用(案例比纯理论好学)
    Linux使用find命令,搜索文件名中带有通配符*,报错: paths must precede expression
  • 原文地址:https://www.cnblogs.com/0803yijia/p/2749038.html
Copyright © 2011-2022 走看看