POJ 2049 Finding Nemo(SPFA)

题目链接

WA+RE了20次。。。错了近20次发现 算法错了,需要注意优先队列,可是,没写过优先队列的BFS。。。虎哥提示用spfa来搞,然后重新了一个spfa的bfs,一次过了。。。注意特殊数据,DISCUSS有很多需要注意的。。。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <iostream>
  5 #include <queue>
  6 using namespace std;
  7 int mp1[501][501],mp2[501][501],o[501][501],sr,sc,in[501][501];
  8 int a[4] = {0,0,1,-1};
  9 int b[4] = {1,-1,0,0};
 10 int bfs()
 11 {
 12     memset(o,127,sizeof(o));//初始化很大的数字
 13     memset(in,0,sizeof(in));
 14     int i,x,y,xx,yy,z,num = 1;
 15     queue<int>quer;
 16     queue<int>quec;
 17     quer.push(sr);
 18     quec.push(sc);
 19     o[sr][sc] = 1;
 20     in[sr][sc] = 1;
 21     while(!quer.empty())
 22     {
 23         num ++;
 24         x = quer.front();
 25         y = quec.front();
 26         quer.pop();
 27         quec.pop();
 28         in[x][y] = 0;
 29         for(i = 0; i <= 3; i ++)
 30         {
 31             xx = x+a[i];
 32             yy = y+b[i];
 33             if(x+a[i] == x-1)
 34                 xx = x;
 35             if(y+b[i] == y-1)
 36                 yy = y;
 37             z = 0;
 38             if(x+a[i]<=199&&x+a[i]>=0&&y+b[i]>=0&&y+b[i]<=199)
 39             {
 40                 if(i <= 1)
 41                 {
 42                     if(mp2[xx][yy] == 1)
 43                         continue;
 44                     else if(mp2[xx][yy] == 0)
 45                     {
 46                         if(o[x+a[i]][y+b[i]] > o[x][y]+1)
 47                         {
 48                             o[x+a[i]][y+b[i]] = o[x][y]+1;
 49                             z = 1;
 50                         }
 51                     }
 52                     else if(mp2[xx][yy] == -1)
 53                     {
 54                         if(o[x+a[i]][y+b[i]] > o[x][y])
 55                         {
 56                             o[x+a[i]][y+b[i]] = o[x][y];
 57                             z = 1;
 58                         }
 59                     }
 60                 }
 61                 else if(i >= 2)
 62                 {
 63                     if(mp1[xx][yy] == 1)
 64                         continue;
 65                     else if(mp1[xx][yy] == 0)
 66                     {
 67                         if(o[x+a[i]][y+b[i]] > o[x][y]+1)
 68                         {
 69                             o[x+a[i]][y+b[i]] = o[x][y]+1;
 70                             z = 1;
 71                         }
 72                     }
 73                     else if(mp1[xx][yy] == -1)
 74                     {
 75                         if(o[x+a[i]][y+b[i]] > o[x][y])
 76                         {
 77                             o[x+a[i]][y+b[i]] = o[x][y];
 78                             z = 1;
 79                         }
 80                     }
 81                 }
 82                 if(!in[x+a[i]][y+b[i]]&&z)
 83                 {
 84                     in[x+a[i]][y+b[i]] = 1;
 85                     quer.push(x+a[i]);
 86                     quec.push(y+b[i]);
 87                 }
 88             }
 89         }
 90     }
 91     if(o[0][0] == 2139062143)
 92         return -1;
 93     else
 94         return o[0][0]-1;
 95 }
 96 int main()
 97 {
 98     int i,j,m,n,x,y,d,t;
 99     double s1,s2;
100     while(scanf("%d%d",&n,&m)!=EOF)
101     {
102         if(n == -1&&m == -1) break;
103         memset(mp1,-1,sizeof(mp1));
104         memset(mp2,-1,sizeof(mp2));
105         for(i = 1; i <= n; i ++)
106         {
107             scanf("%d%d%d%d",&x,&y,&d,&t);
108             if(d == 1)
109             {
110                 for(j = 0; j < t&&y+j <= 199; j ++)
111                 {
112                     mp1[x][y+j] = 1;//mp1[x][y]代表以(x,y)为起点,沿y轴的线段,1代表墙,0代表门。
113                 }
114             }
115             else
116             {
117                 for(j = 0; j < t&&x+j <= 199; j ++)
118                 {
119                     mp2[x+j][y] = 1;//mp2[x][y]代表以(x,y)为起点,沿x轴的线段。
120                 }
121             }
122         }
123         for(i = 1; i <= m; i ++)
124         {
125             scanf("%d%d%d",&x,&y,&d);
126             if(d == 1)
127             {
128                 mp1[x][y] = 0;
129             }
130             else
131             {
132                 mp2[x][y] = 0;
133             }
134         }
135         scanf("%lf%lf",&s1,&s2);
136         if(s1 < 0||s1 > 199||s2 < 0||s2 > 199)//特判
137             printf("0\n");
138         else
139         {
140             sr = (int)s1;
141             sc = (int)s2;
142             printf("%d\n",bfs());
143         }
144     }
145     return 0;
146 }
posted @ 2012-11-29 19:30  Naix_x  阅读(178)  评论(0编辑  收藏  举报