记录编号 9639 评测结果 AAAAAAAAAAAAAAAAAA
题目名称 [POI 1999] 仓库管理员(Store-Keeper) 最终得分 100
用户昵称 GravatarBYVoid 是否通过 通过
代码语言 C++ 运行时间 0.133 s
提交时间 2009-04-08 09:06:00 内存使用 2.49 MiB
显示代码纯文本
  1. /*
  2. * Problem: POI1999 mag
  3. * Author: Guo Jiabao
  4. * Time: 2009.4.7 20:54
  5. * State: Unsolved
  6. * Memo: BFS 双连通分支判断
  7. */
  8. #include <iostream>
  9. #include <cstdio>
  10. #include <cstdlib>
  11. #include <cmath>
  12. #include <cstring>
  13. const int MAXL=101,MAXN=10001,MAXM=MAXN*8;
  14. const int LEFT=0,RIGHT=1,UP=2,DOWN=3;
  15. const int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};
  16. using namespace std;
  17. struct state
  18. {
  19. int x,y,p,step;
  20. };
  21. template<typename T> class linklist
  22. {
  23. public:
  24. T v;
  25. linklist *next;
  26. linklist(T tv):v(tv){next=0;}
  27. };
  28. template<typename T> class Queue
  29. {
  30. public:
  31. linklist<T> *first,*last;
  32. int size;
  33. void clear()
  34. {
  35. size=0;
  36. first=last=0;
  37. }
  38. void ins(T v)
  39. {
  40. size++;
  41. if (first)
  42. last=last->next=new linklist<T>(v);
  43. else
  44. first=last=new linklist<T>(v);
  45. }
  46. T pop()
  47. {
  48. T r=first->v;
  49. linklist<T> *t=first->next;
  50. size--;
  51. delete first;
  52. first=t;
  53. return r;
  54. }
  55. };
  56. struct edge
  57. {
  58. edge *next;
  59. int t;
  60. }ES[MAXM];
  61. edge *V[MAXN];
  62. bool field[MAXL][MAXL],vis[MAXL][MAXL];
  63. bool hash[MAXL][MAXL][4];
  64. int mvb[MAXL][MAXL][4][4],Map[MAXL][MAXL];
  65. int LOW[MAXN],DFN[MAXN],PAR[MAXN],Sta1[MAXM],Sta2[MAXM],Stop,D,Bcnt;
  66. bool isgd[MAXN],bichash[MAXN];
  67. int N,M,Ans,EC=-1,U;
  68. state S,P,T;
  69. Queue<state> Q;
  70. Queue<int> Bel[MAXN];
  71. inline bool inrange(int x,int y)
  72. {
  73. return x>=1 && x<=N && y>=1 && y<=M;
  74. }
  75. inline void addedge(int a,int b)
  76. {
  77. ES[++EC].next=V[a];
  78. V[a]=ES+EC;V[a]->t=b;
  79. ES[++EC].next=V[b];
  80. V[b]=ES+EC;V[b]->t=a;
  81. }
  82. void init()
  83. {
  84. int i,j,k,l;
  85. char c;
  86. freopen("mag.in","r",stdin);
  87. freopen("mag.out","w",stdout);
  88. scanf("%d%d",&N,&M);
  89. for (i=1;i<=N;i++)
  90. {
  91. do c=getchar(); while (c==10 || c==13);
  92. ungetc(c,stdin);
  93. for (j=1;j<=M;j++)
  94. {
  95. c=getchar();
  96. if (c=='S')
  97. field[i][j]=false;
  98. else
  99. {
  100. field[i][j]=true;
  101. Map[i][j]=++U;
  102. k=i-1,l=j;
  103. if (inrange(k,l) && field[k][l])
  104. addedge(Map[i][j],Map[k][l]);
  105. k=i,l=j-1;
  106. if (inrange(k,l) && field[k][l])
  107. addedge(Map[i][j],Map[k][l]);
  108. }
  109. if (c=='M')
  110. {
  111. S.x=i;S.y=j;
  112. S.step=0;S.p=0;
  113. }
  114. if (c=='P')
  115. P.x=i,P.y=j;
  116. if (c=='K')
  117. T.x=i,T.y=j;
  118. for (k=0;k<4;k++)
  119. for (l=0;l<4;l++)
  120. mvb[i][j][k][l]=2;
  121. }
  122. }
  123. }
  124. inline int getopd(int k)
  125. {
  126. if (k==LEFT) return RIGHT;
  127. if (k==RIGHT) return LEFT;
  128. if (k==UP) return DOWN;
  129. return UP;
  130. }
  131. bool start(state i)
  132. {
  133. int k,r;
  134. for (k=0;k<4;k++)
  135. {
  136. state j;
  137. j.x=i.x+dx[k]; j.y=i.y+dy[k];
  138. if (inrange(j.x,j.y) && field[j.x][j.y] && !vis[j.x][j.y])
  139. {
  140. vis[j.x][j.y]=true;
  141. if (j.x==P.x && j.y==P.y)
  142. {
  143. P.p=getopd(k);
  144. return true;
  145. }
  146. else
  147. r=start(j);
  148. if (r) return true;
  149. }
  150. }
  151. return false;
  152. }
  153. inline bool insamebic(int u,int v)
  154. {
  155. linklist<int> *k;
  156. bool rs=false;
  157. for (k=Bel[u].first;k;k=k->next)
  158. bichash[k->v]=true;
  159. for (k=Bel[v].first;k;k=k->next)
  160. if (bichash[k->v])
  161. {
  162. rs=true;
  163. break;
  164. }
  165. for (k=Bel[u].first;k;k=k->next)
  166. bichash[k->v]=false;
  167. return rs;
  168. }
  169. bool movable(int bx,int by,int ps,int pd)
  170. {
  171. if (mvb[bx][by][ps][pd]==2)
  172. {
  173. if (isgd[Map[bx][by]])
  174. {
  175. int k=ps,x,y;
  176. state p,q;
  177. p.x=bx+dx[k]; p.y=by+dy[k];
  178. k=pd;
  179. q.x=bx+dx[k]; q.y=by+dy[k];
  180. x=Map[p.x][p.y]; y=Map[q.x][q.y];
  181. mvb[bx][by][ps][pd]=insamebic(x,y);
  182. }
  183. else
  184. mvb[bx][by][ps][pd]=true;
  185. }
  186. return mvb[bx][by][ps][pd];
  187. }
  188. bool BFS()
  189. {
  190. state i,j;
  191. int k;
  192. Q.clear();
  193. Q.ins(P);
  194. hash[P.x][P.y][P.p]=true;
  195. while (Q.size)
  196. {
  197. i=j=Q.pop();
  198. // printf("(%d,%d)\n",Map[i.x][i.y],i.p);
  199. //move direction
  200. for (k=0;k<4;k++)
  201. {
  202. j.x=i.x+dx[k]; j.y=i.y+dy[k];
  203. if (inrange(j.x,j.y) && field[j.x][j.y])
  204. {
  205. j.x=i.x;j.y=i.y;j.p=k;
  206. if (!hash[j.x][j.y][j.p] && movable(i.x,i.y,i.p,j.p))
  207. {
  208. hash[j.x][j.y][j.p]=true;
  209. Q.ins(j);
  210. }
  211. }
  212. }
  213. j.step=i.step+1;
  214. //push box
  215. k=getopd(i.p);
  216. j.x=i.x+dx[k]; j.y=i.y+dy[k]; j.p=i.p;
  217. if (inrange(j.x,j.y) && field[j.x][j.y] && !hash[j.x][j.y][j.p])
  218. {
  219. if (j.x==T.x && j.y==T.y)
  220. {
  221. Ans=j.step;
  222. return true;
  223. }
  224. hash[j.x][j.y][j.p]=true;
  225. Q.ins(j);
  226. }
  227. }
  228. return false;
  229. }
  230. void addbic(int B,int u)
  231. {
  232. linklist<int> *k;
  233. for (k=Bel[u].first;k;k=k->next)
  234. if (k->v==B)
  235. return;
  236. Bel[u].ins(B);
  237. }
  238. void bic(int u,int p)
  239. {
  240. DFN[u]=LOW[u]=++D;
  241. for (edge *k=V[u];k;k=k->next)
  242. {
  243. int v=k->t;
  244. if (v==p) continue;
  245. if (DFN[v]<DFN[u]) //避免横叉边
  246. {
  247. Stop++;Sta1[Stop]=u;Sta2[Stop]=v;
  248. if (!DFN[v])
  249. {
  250. bic(v,u);
  251. if (LOW[v]<LOW[u])
  252. LOW[u]=LOW[v];
  253. if (DFN[u]<=LOW[v])
  254. {
  255. isgd[u]=true;
  256. int x,y;
  257. Bcnt++;
  258. do
  259. {
  260. x=Sta1[Stop];y=Sta2[Stop];
  261. Stop--;
  262. addbic(Bcnt,x);
  263. addbic(Bcnt,y);
  264. }
  265. while (!(x==u && y==v || x==v && y==u));
  266. }
  267. }
  268. else if (DFN[v]<LOW[u])
  269. LOW[u]=DFN[v];
  270. }
  271. }
  272. }
  273. void solve()
  274. {
  275. bic(1,0);
  276. if (start(S) && BFS())
  277. printf("%d\n",Ans);
  278. else
  279. printf("NIE\n");
  280. }
  281. int main()
  282. {
  283. init();
  284. solve();
  285. return 0;
  286. }