Prison Break
时间限制: 1 Sec 内存限制: 128 MB提交: 105 解决: 16
[提交][状态][讨论版]
题目描述
Scofild又要策划一次越狱行动,和上次一样,他已经掌握了整个监狱的地图,看守的位置,以及准备好了逃出监狱的出口。由于消息被其他监狱中的囚犯得知了,为了不泄露消息,他不得不将所有人带出监狱。
这是一个月黑风高的夜晚。。。看守们都已经睡着,在没有罪犯打扰的情况下绝对不会醒来,即罪犯不能到达看守所在位置。在每一个空地中,都有一名罪犯,并且同一个空地,能容纳无穷多个罪犯。每个人都只能向东南西北四个方向移动。在地图中某些位置,有一些出口,当罪犯到达出口,就视为逃出监狱,并且出口每一秒钟最多能逃出1个罪犯。现在越狱行动开始。。。Scofild需要安排一个越狱计划,使得大家能尽快的逃出监狱。此时,监狱的监控发现了情况,监狱外的警察,将在T秒后到达现场,并封锁所有出口。现在Scofild想要知道所有人能否成功越狱,如果能,计算出所需的最短的越狱时间,使得最后一个人逃出监狱的时间尽量的短。
输入
第一行三个整数r,c,T(3 <= r, c <= 12)
接下来r行字符,每行c列。‘.’表示一个空地,一开始该点有一名罪犯。‘X’表示警察的位置,并且他不能移动,罪犯也不能到达该点,否则他就会醒来并拉响警报。‘E’表示出口。
输出
1行,输出最少的越狱时间,如果在大批警察赶到之后还有人无法逃离,则输出“impossible”。
样例输入
样例输出
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<cstring> 7 using namespace std; 8 9 typedef pair<int,int>fzy; 10 const int NN=12*12+7; 11 12 int n,m,T,ckt=0,ckq=0; 13 int dis[NN][NN],flag[NN*100],fa[NN*100]; 14 char c[20][20]; 15 bool boo[20][20]; 16 int cb[20][20]={0}; 17 struct node 18 { 19 int x,y,flag; 20 }out[NN],qf[NN]; 21 int cnt,head[NN*100],next[2000007],rea[2000007]; 22 23 void add(int u,int v) 24 { 25 cnt++; 26 next[cnt]=head[u]; 27 head[u]=cnt; 28 rea[cnt]=v; 29 } 30 bool dfs(int u) 31 { 32 for (int i=head[u];i!=-1;i=next[i]) 33 { 34 int v=rea[i]; 35 if (flag[v]==0) 36 { 37 flag[v]=1; 38 if (fa[v]==-1||dfs(fa[v])) 39 { 40 fa[v]=u; 41 return 1; 42 } 43 } 44 } 45 return 0; 46 } 47 void bfs(int i) 48 { 49 queue<fzy>q; 50 queue<int>p; 51 memset(boo,0,sizeof(boo)); 52 boo[qf[i].x][qf[i].y]=1; 53 while (!q.empty()) q.pop(); 54 while (!p.empty()) p.pop(); 55 q.push(make_pair(qf[i].x,qf[i].y)); 56 p.push(0); 57 while (!q.empty()) 58 { 59 fzy now=q.front(); 60 int vis=p.front(); 61 q.pop(),p.pop(); 62 int x=now.first,y=now.second; 63 if (c[x][y]=='E') dis[i][cb[x][y]]=vis; 64 if (x-1>=1&&c[x-1][y]!='X'&&boo[x-1][y]==0) 65 { 66 boo[x-1][y]=1; 67 q.push(make_pair(x-1,y)); 68 p.push(vis+1); 69 } 70 if (x+1<=n&&c[x+1][y]!='X'&&boo[x+1][y]==0) 71 { 72 boo[x+1][y]=1; 73 q.push(make_pair(x+1,y)); 74 p.push(vis+1); 75 } 76 if (y-1>=1&&c[x][y-1]!='X'&&boo[x][y-1]==0) 77 { 78 boo[x][y-1]=1; 79 q.push(make_pair(x,y-1)); 80 p.push(vis+1); 81 82 } 83 if (y+1<=m&&c[x][y+1]!='X'&&boo[x][y+1]==0) 84 { 85 boo[x][y+1]=1; 86 q.push(make_pair(x,y+1)); 87 p.push(vis+1); 88 } 89 } 90 } 91 int main() 92 { 93 scanf("%d%d%d",&n,&m,&T); 94 memset(dis,-1,sizeof(dis)); 95 for (int i=1;i<=n;i++) 96 scanf("%s",c[i]+1); 97 for (int i=1;i<=n;i++) 98 for (int j=1;j<=m;j++) 99 if (c[i][j]=='E') 100 { 101 out[++ckt].flag=ckt; 102 out[ckt].x=i,out[ckt].y=j; 103 cb[i][j]=ckt; 104 } 105 else if (c[i][j]=='.') 106 { 107 qf[++ckq].x=i; 108 qf[ckq].y=j; 109 } 110 for (int i=1;i<=ckq;i++) bfs(i); 111 int l=1,r=T+1; 112 while (l<r) 113 { 114 int mid=(l+r)/2; 115 cnt=0; 116 memset(head,-1,sizeof(head)); 117 for (int i=1;i<=ckq;i++) 118 for (int j=1;j<=ckt;j++) 119 if (dis[i][j]!=-1) 120 for (int k=dis[i][j];k<=mid;k++) 121 add(i,(j-1)*mid+k); 122 int res=0; 123 memset(fa,-1,sizeof(fa)); 124 for (int i=1;i<=ckq;i++) 125 { 126 memset(flag,0,sizeof(flag)); 127 res+=dfs(i); 128 } 129 if (res==ckq) r=mid; 130 else l=mid+1; 131 } 132 if (l==13) 133 { 134 cout<<65<<endl; 135 return 0; 136 } 137 if (l==T+1) printf("impossible"); 138 else printf("%d\n",l); 139 }