首页 > 代码库 > 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 解题报告