「LuoguP3191」 [HNOI2007]緊急疏散EVACUATE

Description


發生了火警,所有人員需要緊急疏散!假設每個房間是一個N M的矩形區域。每個格子如果是’.’,那麼表示這是一塊空地;如果是’X’,那麼表示這是一面牆,如果是’D’,那麼表示這是一扇門,人們可以從這兒撤出房間。已知門一定在房間的邊界上,並且邊界上不會有空地。最初,每塊空地上都有一個人,在疏散的時候,每一秒鐘每個人都可以向上下左右四個方向移動一格,當然他也可以站着不動。疏散開始後,每塊空地上就沒有人數限制了(也就是說每塊空地可以同時站無數個人)。但是,由於門很窄,每一秒鐘只能有一個人移動到門的位置,一旦移動到門的位置,就表示他已經安全撤離了。現在的問題是:如果希望所有的人安全撤離,最短需要多少時間?或者告知根本不可能。

Input


輸入文件第一行是由空格隔開的一對正整數N與M,3<=N <=20,3<=M<=20,以下N行M列描述一個N M的矩陣。其中的元素可爲字符’.’、’X’和’D’,且字符間無空格。

Output


只有一個整數K,表示讓所有人安全撤離的最短時間,如果不可能撤離,那麼輸出’impossible’(不包括引號)。

Sample Input


5 5
XXXXX
X…D
XX.XX
X..XX
XXDXX

Sample Output


3

Hint


2015.1.12新加數據一組,鳴謝1756500824

C++語言請用scanf(“%s”,s)讀入!

題解


首先這只是90分代碼並且已經手推出數據被卡 也許是代碼問題也許是思路問題(遍歷題解並沒有同樣的思路但是我真的調了好幾個小時了要吐了

首先讀題很容易想到二分答案

拆點,設空地< i.a >,< i.b > 門< d.a >,< d.b >,設二分的答案爲k

從S到每個< i.a >連邊爲1

每個< i.a >向< i.b >連k,每個< d.a >向< d.b >連k

然後從每個門開始dfs dfs的第一個空地< i.b >向< d.a >連k,之後按dfs序 後掃到的空地的< i2.b >向前一個的< i1.a >連k

最後每一個< d.b >向T連k

注意網絡流的二分答案一般都要復原操作(把反邊流量加到正邊上 清空反邊流量)

這道題真的噁心到嘔吐 有朝一日過了我給你黑

醜到我都不想看的代碼真的醜到哭泣

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=99999999;
char tu[27][27];
int n,m;
int flag=0;
void scan()
{
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    cin>>tu[i][j];
    return;
}
int s,t;
int num[27][27];
int ss;
bool sf[27][27];
int mx[5]={0,1,0,-1,0};
int my[5]={0,0,1,0,-1};
struct emm{
    int e,f,v;
}a[1000007];
int h[807];
int tot=1;
void con(int x,int y,int l)
{
    a[++tot].f=h[x];
    h[x]=tot;
    a[tot].e=y;
    a[tot].v=l;
    a[++tot].f=h[y];
    h[y]=tot;
    a[tot].e=x;
    a[tot].v=0;
    return;
}
/*
void dfss(int x,int y)
{
    sf[x][y]=1;
    for(int i=1;i<=4;++i)
    {
        x+=mx[i],y+=my[i];
        if((tu[x][y]=='.'||tu[x][y]=='D')&&!sf[x][y])
        {
            con(num[x][y],ss,1);
            //dfss(x,y);
        }
        x-=mx[i],y-=my[i];
    }
    return;
}
*/
int tag,peo=0;
void dfsss(int bx,int by,int x,int y,int k)
{
    con(num[x][y]+m*n,num[bx][by],k);
    int bbx=x,bby=y;
    sf[x][y]=1;
    for(int i=1;i<=4;++i)
    {
        x+=mx[i],y+=my[i];
        if(tu[x][y]=='.'&&!sf[x][y])dfsss(bbx,bby,x,y,k);
        x-=mx[i],y-=my[i];
    }
    return;
}
void build()
{
    s=0,t=2*m*n+1;
    int tim=0;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    num[i][j]=++tim;
    num[0][0]=t;

    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='.'){
        con(s,num[i][j],1);
        peo++;
    }
    /*
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='D'||tu[i][j]=='.'){
        memset(sf,0,sizeof(sf));
        ss=num[i][j];
        dfss(i,j);
    }
    */
    tag=tot;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='.'||tu[i][j]=='D')con(num[i][j],num[i][j]+m*n,-1);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='D'){
    memset(sf,0,sizeof(sf));
    dfsss(0,0,i,j,-1);
    }
    return;
}
void conn(int x,int y,int k)
{
    //cout<<x<<" "<<y<<endl;
    a[++tot].v=k;
    a[++tot].v=0;
    return;
}
void dfss(int bx,int by,int x,int y,int k)
{
    conn(num[x][y]+m*n,num[bx][by],k);
    int bbx=x,bby=y;
    sf[x][y]=1;
    for(int i=1;i<=4;++i)
    {
        x+=mx[i],y+=my[i];
        if(tu[x][y]=='.'&&!sf[x][y])dfss(bbx,bby,x,y,k);
        x-=mx[i],y-=my[i];
    }
    return;
}
void adbuild(int k)
{
    //cout<<"adbuild"<<k<<endl;
    //cout<<"a"<<endl;
    tot=tag;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='.'||tu[i][j]=='D')conn(num[i][j],num[i][j]+m*n,k);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    if(tu[i][j]=='D'){
    memset(sf,0,sizeof(sf));
    dfss(0,0,i,j,k);
    }
    return;
}
queue<int>q;
int d[807];
inline bool bfs()
{
    memset(d,0,sizeof(d));
    d[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=h[x];i;i=a[i].f)
        if(!d[a[i].e]&&a[i].v)
        {
            d[a[i].e]=d[x]+1;
            q.push(a[i].e);
        }
    }
    return d[t];
}
int dfs(int x,int al)
{
    if(x==t||!al)return al;
    int fl=0;
    for(int i=h[x];i;i=a[i].f)
    if(d[a[i].e]==d[x]+1&&a[i].v)
    {
        if(flag)cout<<x<<" "<<a[i].e<<endl;
        int f=dfs(a[i].e,min(a[i].v,al));
        if(f)
        {
            fl+=f;
            al-=f;
            a[i].v-=f;
            a[i^1].v+=f;
            if(!al)break;
        }
    }
    if(!fl)d[x]=-1;
    return fl;
}
void erfen(int l,int r)
{
    //cout<<"l="<<l<<" r="<<r<<endl;
    if(l==r){if(r==peo+1)cout<<"impossible"<<endl;else cout<<l<<endl;return;}
    int mid=(l+r)/2;
    if(mid==6)flag=1;else flag=0;
    for(int i=2;i<=tag;i+=2){a[i].v+=a[i^1].v;a[i^1].v=0;}
    adbuild(mid);
    int ans=0;
    while(bfs()){ans+=dfs(s,INF);if(flag)cout<<ans<<endl;}
    //cout<<"mid="<<mid<<" ans="<<ans<<endl;
    if(ans==peo)erfen(l,mid);
    else erfen(mid+1,r);
    return;
}
int main()
{
    //freopen("a.in","r",stdin);
    scan();
    build();
    erfen(0,peo+1);
    return 0;
}

出鍋數據:

4 4
...D
.XX.
....
XD.X

手推ans=6 程序輸出7

再 也 不 想 調 了

如果有dalao能看穿的話就 救救孩子

深鞠躬QAQ

發佈了31 篇原創文章 · 獲贊 5 · 訪問量 1881
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章