首页 > 代码库 > POJ3057 Evacuation 解题报告
POJ3057 Evacuation 解题报告
这道题的难点应该就是想到这是一道二分图匹配
想到这点以后,就是建图了
//by baobaopangzi88#include <iostream>#include <sstream>#include <ios>#include <iomanip>#include <functional>#include <algorithm>#include <vector>#include <string>#include <list>#include <queue>#include <deque>#include <stack>#include <set>#include <map>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <climits>#include <cctype>#define INF 0x3f3f3f3f#define MP(X,Y) make_pair(X,Y)#define PB(X) push_back(X)#define REP(X,N) for(int X=0;X<N;X++)#define REP2(X,L,R) for(int X=L;X<=R;X++)#define DEP(X,R,L) for(int X=R;X>=L;X--)#define CLR(A,X) memset(A,X,sizeof(A))#define IT iterator#define PI 3.14159265358979323846#define _ ios_base::sync_with_stdio(0);cin.tie(0);#define X first#define Y second#define MAX_V 10101#define maxn 13using namespace std;typedef long long ll;typedef pair<int,int>PII;int n,m,V;char M[maxn][maxn];vector<int> G[30000];vector<int >dx,dy,px,py;int D[maxn][maxn][maxn][maxn];int Dx[4]={-1,1,0,0},Dy[4]={0,0,-1,1};int match[30000];bool used[30000];void add_edge(int from,int to){ G[from].PB(to); G[to].PB(from);}bool dfs(int v){ used[v]=1; for(int i=0;i<G[v].size();++i){ int to=G[v][i],w=match[to]; if(w<0 || !used[w] && dfs(w)){ match[v]=to; match[to]=v; return true; } } return false;}void bfs(int x,int y,int D[maxn][maxn]){ D[x][y]=0; queue<int >qx,qy; qx.push(x); qy.push(y); while(!qx.empty()){ x=qx.front();qx.pop(); y=qy.front();qy.pop(); for(int i=0;i<4;++i){ int nx=x+Dx[i],ny=y+Dy[i]; if(nx>=0 && nx<n && ny>=0 && ny<m && M[nx][ny]==‘.‘ && D[nx][ny]<0){ D[nx][ny]=D[x][y]+1; qx.push(nx); qy.push(ny); } } }}int solve(){ dx.clear();dy.clear(); px.clear();py.clear(); memset(D,-1,sizeof(D)); for(int i=0;i<n;++i) for(int j=0;j<m;++j){ if(M[i][j]==‘D‘){ dx.PB(i); dy.PB(j); bfs(i,j,D[i][j]); } else if(M[i][j]==‘.‘){ px.PB(i); py.PB(j); } } //build_graph int temp=n*m;//时间的最大数 int d=dx.size(),p=px.size(); V=n*m*d+p; for(int v=0;v<V;++v) G[v].clear(); for(int i=0;i<d;++i) for(int j=0;j<p;++j) for(int t=0;t<temp;++t){ if(D[dx[i]][dy[i]][px[j]][py[j]]>0 && D[dx[i]][dy[i]][px[j]][py[j]]<=t+1){ add_edge(t*d+i,temp*d+j); } } if(p==0) return 0; int res=0; memset(match,-1,sizeof(match)); for(int t=0;t<temp;++t){ for(int v=t*d;v<(t+1)*d;++v){ if(match[v]<0){ memset(used,0,sizeof(used)); if(dfs(v)){ res++; } } } if(res==p) return t+1; } return -1;}int main(){ int T; cin>>T; while(T--){ cin>>n>>m; for(int i=0;i<n;++i) cin>>M[i]; int temp=solve(); if(temp<0) cout<<"impossible"<<endl; else cout<<temp<<endl; } return 0;}
POJ3057 Evacuation 解题报告
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。