题解 poj3057 Evacuation
Posted white-star
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 poj3057 Evacuation相关的知识,希望对你有一定的参考价值。
算法:匈牙利算法
复杂度:不好算,懒得算
这道题我调了两个半小时,代码长,细节多,现总结一下栽过的坑
- 此题数组传参的方式很好,能够降低代码难度,值得学习
- 如何使人和时间、门的二元组互不冲突很重要
- 如果点无冲突用链表,否则用vector
- 点是从0开始建的,初始化match数组不能用0,我虽然注意到了这一点却没调出来
丑陋的代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;++i)
#define go(i,a,b) for(int i=a;i<=b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
const int N=1000010;
int n,m,d[15][15][15][15],match[N],cnt=0,tot=0,head[N],p,door,ans=0;
int match2[N];
bool vis[N];
char g[15][15];
int nd[4][2]= 1,0,-1,0,0,1,0,-1,V;
vector<int> dx,dy,px,py,e[250];
/*struct edge
int nxt,v;
e[N];
void add(int u,int v)
e[cnt]=(edge)head[u],v;
head[u]=cnt++;
*/
void add(int u,int v)
e[u].push_back(v);
void bfs(int x,int y,int d[15][15])
queue<int>qx,qy;
d[x][y]=0;
qx.push(x),qy.push(y);
while(!qx.empty())
x=qx.front();qx.pop();
y=qy.front();qy.pop();
go(k,0,3)
int x2=x+nd[k][0],y2=y+nd[k][1];
if(g[x2][y2]=='.'&&d[x2][y2]<0)
d[x2][y2]=d[x][y]+1;
qx.push(x2),qy.push(y2);
bool dfs(int u)
/*for(int i=head[u];i+1;i=e[i].nxt)
int v=e[i].v;
if(vis[v]) continue;
vis[v]=1;
if(!match[v]||dfs(match[v]))
match[v]=u;match[u]=v;
return 1;
*/
for(int i=0;i<e[u].size();++i)
int v=e[u][i];
if(vis[v]) continue;
vis[v]=1;
if(match[v]==-1||dfs(match[v]))
match[v]=u;match2[u]=v;
return 1;
return 0;
void work(int k)
for(int i=0;i<p;++i)
if(match2[i]==-1)
for(int j=0;j<door*k;j++) vis[j]=false;
ans+=dfs(i);
void solve()
tot=n*m;
dx.clear(),dy.clear(),px.clear(),py.clear();
go(i,0,p-1)
e[i].clear();
mem(d,-1);
rep(x,0,n)
rep(y,0,m)
if(g[x][y]=='D')
dx.push_back(x),dy.push_back(y);
bfs(x,y,d[x][y]);
else if(g[x][y]=='.')
px.push_back(x),py.push_back(y);
door=dx.size(),p=px.size();
if(!p)
puts("0");
return;
mem(match,-1);mem(match2,-1);
mem(head,-1);cnt=0;
ans=0;
int k;
for(k=1;k<tot;++k)
//for(int i=0;i<=30;++i) printf("%d %d ",match[i],match2[i]);
//puts("");
rep(i,0,p)
rep(j,0,door)
//printf("%d\n",d[dx[j]][dy[j]][px[i]][py[i]]);
if(d[dx[j]][dy[j]][px[i]][py[i]]!=-1&&d[dx[j]][dy[j]][px[i]][py[i]]<=k)
add(i,j+door*(k-1));
work(k);
// printf("%d\n",ans);
if(ans==p)
printf("%d\n",k);
return;
if(k==tot) puts("impossible");
return;
int main()
//freopen("input.txt","r",stdin);
//freopen("wrong.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
cin>>n>>m;
go(i,0,n-1) scanf("%s",g[i]);
//printf("%d\n",T);
solve();
//int x=5;
//printf("%d",x*x);
return 0;
以上是关于题解 poj3057 Evacuation的主要内容,如果未能解决你的问题,请参考以下文章