题目:
题意:
有人,门(只有边上有,且1s只能出去一个人),和墙,每s人可移动一个格子,问多少秒所有人可以逃出,逃不出输出“impossible”
分析:
首先,我们先想着样一个问题,如果这个人在某一秒可以到达了这个们,他将可以在这1s之后的任一没人通过此门的时刻出门。而且题意说每个门每一刻只能使1人通过,那么我们可以直接把门分成好多门(1s一个,当然时间有上线),然后让人和这些门去匹配就好了,看一下第几秒可以人都匹配上就好了,当然我们加一个二分不要一个一个跑了,最后复杂度:10(二分)*10*10(人)*10*10(人)*44(门)*100(时间)(有些估算的较大),有点大,不过还是可以的,毕竟这样求匹配的常熟是很小的。当然有人写的是用D去匹配.然后不用二分了,但是这样的复杂度更大了,它是10*10(人)*44(门)*100(时间)*44(门)*100(时间),而且常数可能也大了。最后就是代码。
#include <cstdio> #include <queue> #include <cstring> using namespace std; char ch[13][13]; const int maxn=12*12*44*100+10; struct E{ int to; int next; int val; }ed[maxn]; int head[maxn],ma[maxn],tot; bool vis[13][13]; void J(int a,int b,int c){ ed[++tot].to=b; ed[tot].val=c; ed[tot].next=head[a]; head[a]=tot; } struct Node{ int x,y,t; Node(){} Node(int a,int b,int c){x=a;y=b;t=c;} }; int x,y; queue<Node> qu; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int M1(int a,int b){return y*(a-1)+b;} int M2(int a,int b,int t){return (M1(a,b)-1)*100+t;} void JIA(int a,int b,int nx,int ny,int t){ for(int i=t;i<=100;i++) J(M1(a,b),M2(nx,ny,i),i); } void Bfs(int a,int b){ memset(vis,0,sizeof(vis)); vis[a][b]=1; qu.push(Node(a,b,0)); while(!qu.empty()){ Node js=qu.front(); qu.pop(); for(int i=0;i<4;i++){ int nx=js.x+dx[i],ny=js.y+dy[i]; if(nx>=1&&nx<=x&&ny>=1&&ny<=y&&!vis[nx][ny]&&ch[nx][ny]=='.'){ vis[nx][ny]=1; qu.push(Node(nx,ny,js.t+1)); } if(nx>=1&&nx<=x&&ny>=1&&ny<=y&&!vis[nx][ny]&&ch[nx][ny]=='D'){ vis[nx][ny]=1; JIA(a,b,nx,ny,js.t+1); } } } } bool vis2[maxn]; bool Dfs(int x,int t){ for(int i=head[x];i;i=ed[i].next){ if(vis2[ed[i].to]||ed[i].val>t) continue; vis2[ed[i].to]=1; if(ma[ed[i].to]==0||Dfs(ma[ed[i].to],t)){ma[ed[i].to]=x;return 1;} } return 0; } bool pd(int t){ memset(ma,0,sizeof(ma)); for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) if(ch[i][j]=='.'){ memset(vis2,0,sizeof(vis2)); if(!Dfs(M1(i,j),t)) return 0; } return 1; } int main(){ int t; scanf("%d",&t); for(int jsjs=1;jsjs<=t;jsjs++){ scanf("%d%d",&x,&y); memset(head,0,sizeof(head)); tot=0; for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) scanf(" %c",&ch[i][j]); for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) if(ch[i][j]=='.') Bfs(i,j); int l=0,r=100; while(l<=r){ int mid=(l+r)/2; if(pd(mid)) r=mid-1; else l=mid+1; } if(l==101) printf("impossible\n"); else printf("%d\n",l); } return 0; }