POJ 3057-Evacuation
分析
这个题想了半天。
最开始想的是不断地BFS,但这样不仅时间复杂度没有保障,而且正确性可能也有问题。
如果门是固定的,还可以考虑像曾经一个题那么做,但现在不行了,因为门不仅不固定,而且还有很多个。
但有一个性质可以考虑,就是每扇门在某一时刻只能走出一个人。
不难想到二分图匹配。
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=15,M=1e5+10;
struct Node{
int x,y;
Node(){}
Node(int a,int b){
x=a;y=b;
}
};
struct Edge{
int to,nxt;
}e[M*100];
int h[10*M],idx;
void Ins(int a,int b){
e[++idx].to=b;e[idx].nxt=h[a];h[a]=idx;
}
char map[N][N],vis[M];
int match[M*10],dis[N][N],d[N][N][N][N],n,m;
vector <Node > pi,di;
void bfs(int x,int y){
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
memset(dis,-1,sizeof(dis));
dis[x][y]=0;
queue<Node > q;
q.push(Node(x,y));
while(!q.empty()){
Node u=q.front();q.pop();
for(int i=0;i<4;i++){
int ux=u.x+dx[i];
int uy=u.y+dy[i];
if(ux>=0&&uy>=0&&ux<n&&uy<m){
if(map[ux][uy]=='.'&&dis[ux][uy]==-1){
dis[ux][uy]=dis[u.x][u.y]+1;
d[x][y][ux][uy]=dis[ux][uy];
q.push(Node(ux,uy));
}
}
}
}
}
bool dfs(int x){
vis[x]=1;
for(int i=h[x];i;i=e[i].nxt){
int v=e[i].to;
if(match[v]==-1||!vis[match[v]]&&dfs(match[v])){
match[v]=x;
match[x]=v;
return 1;
}
}
return 0;
}
int sum(int x){
for(int i=0;i<pi.size();i++)
for(int j=0;j<di.size();j++){
int px=pi[i].x,py=pi[i].y;
int dx=di[j].x,dy=di[j].y;
if(d[dx][dy][px][py]<=x){
Ins(x*di.size()+j,(n*m+10)*di.size()+10+i);
Ins((n*m+10)*di.size()+10+i,x*di.size()+j);
}
}
int tot=0;
for(int i=0;i<di.size();i++){
int u=i+x*di.size();
if(match[u]==-1){
memset(vis,0,sizeof(vis));
if(dfs(u))tot++;
}
}
return tot;
}
void calc(){
memset(match,-1,sizeof(match));
int tot=0;
for(int i=0;i<=m*n+3;i++){
tot+=sum(i);
if(tot>=pi.size()){
printf("%d\n",i);
return ;
}
}
printf("impossible\n");
}
int main(){
int T;
scanf("%d",&T);
while(T--){
idx=0;
pi.clear();di.clear();
memset(d,0x3f,sizeof(d));
memset(h,0,sizeof(h));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",map[i]);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(map[i][j]=='D'){
di.push_back(Node(i,j));
bfs(i,j);
}else if(map[i][j]=='.'){
pi.push_back(Node(i,j));
}
}
}
calc();
}
}
int - > long long
0 - > 100