poj 3057 Evacuation

来源:互联网 发布:淘宝联盟拍了却没订单 编辑:程序博客网 时间:2024/06/05 15:54

二分图匹配

#include<iostream>#include<sstream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<map>#include<set>#include<string>#include<vector>#include<algorithm>using namespace std;#define inf 0x7ffffff#define lc l,m,index<<1#define rc m+1,r,index<<1|1#define max_n 100005#define mod 1000000007#define FOR(i,s,t) for(int i=(s);i<=(t);++i)const int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};char field[1005][1005];int dist[50][50][50][50];int X,Y;vector<int>dX,dY;vector<int>pX,pY;vector<int>G[max_n];int match[max_n];bool used[max_n];bool dfs(int v){    used[v]=1;    for(int i=0;i<G[v].size();i++)    {        int u=G[v][i],w=match[u];        if(w<0 || !used[w] && dfs(w))        {            match[u]=v;            match[v]=u;            return 1;        }    }    return 0;}void add_edge(int u,int v){    G[u].push_back(v);    G[v].push_back(u);}void bfs(int x,int y,int d[50][50]){    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();        for(int i=0;i<4;i++)        {            int x2=x+dx[i];            int y2=y+dy[i];            if(x2>=0 && x2<X && y2>=0 && y2<Y && field[x2][y2]=='.' && d[x2][y2]<0)            {                d[x2][y2]=d[x][y]+1;                qx.push(x2);                qy.push(y2);            }        }    }}void solve(){    int n=X*Y;    dX.clear();    dY.clear();    pX.clear();    pY.clear();    for(int i=0;i<=n*n;i++)    G[i].clear();    memset(dist,-1,sizeof(dist));    for(int i=0;i<X;i++)    {        for(int j=0;j<Y;j++)        {            if(field[i][j]=='D')            {                dX.push_back(i);                dY.push_back(j);                bfs(i,j,dist[i][j]);            }            else if(field[i][j]=='.')            {                pX.push_back(i);                pY.push_back(j);            }        }    }    int d=dX.size(),p=pX.size();    for(int i=0;i<d;i++)    {        for(int j=0;j<p;j++)        {            if(dist[dX[i]][dY[i]][pX[j]][pY[j]]>=0)            {                for(int k=dist[dX[i]][dY[i]][pX[j]][pY[j]];k<=n;k++)                {                    add_edge((k-1)*d+i,n*d+j);                }            }        }    }    if(p==0)    {        printf("0\n");        return ;    }    int num=0;    memset(match,-1,sizeof(match));    for(int v=0;v<n*d;v++)    {        memset(used,0,sizeof(used));        if(dfs(v))        {            if(++num==p)            {                printf("%d\n",v/d+1);                return ;            }        }    }    printf("impossible\n");}int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(field,0,sizeof(field));        scanf("%d%d",&X,&Y);        for(int i=0;i<X;i++)        scanf("%s",field[i]);        solve();    }    return 0;}


0 0