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 }