• BZOJ1189:[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

    Solution

    $Update$:写假了,先别看了QwQ

    这个题……有点像跳舞那个题emmmm……
    答案肯定是满足单调性的,所以我们可以枚举
    (可以和跳舞那个题一样二分,不过二分就要每次重新添加边,太麻烦)
    先判断impossible,BFS判断就行。
    建图:超级源点-人-门-超级汇点
    枚举秒数,每一秒就在门和超级汇点间连一条容量1的边,意味着当前秒这个门可以多出一个人了
    若某个人到某个门耗费的时间为当前秒数,就在人和门间连一条容量为1的边
    之后跑一边最大流,若最大流为人数的话就说明人可以全跑出去了
    PS每次跑最大流的时候之前的Ans不能清零emmm

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cmath>
      6 #define MAXM (100000+10)
      7 #define MAXN (1010+10)
      8 using namespace std;
      9 struct node
     10 {
     11     int Flow;
     12     int next;
     13     int to;
     14 }edge[MAXM*2];
     15 int Depth[MAXN],Q[MAXN];
     16 int head[MAXN],num_edge;
     17 int n,m,s,e=999,d,INF;
     18 int a[MAXN][MAXN];
     19 int num[MAXN][MAXN];
     20 int dis[MAXN][MAXN];
     21 int PEOPLE[MAXN],P_sum;
     22 int DOOR[MAXN],D_sum;
     23 int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
     24 int q[1005][3];
     25 int Ans;
     26 bool used[505][505];
     27 char ch[1005];
     28 
     29 void add(int u,int v,int l)
     30 {
     31     edge[++num_edge].to=v;
     32     edge[num_edge].Flow=l;
     33     edge[num_edge].next=head[u];
     34     head[u]=num_edge;
     35 }
     36 
     37 bool Bfs(int s,int e)
     38 {
     39     int Head=0,Tail=1;
     40     memset(Depth,0,sizeof(Depth));
     41     Depth[s]=1;
     42     Q[1]=s;
     43     while (Head<Tail)
     44     {
     45         int x=Q[++Head];
     46         for (int i=head[x];i!=0;i=edge[i].next)
     47             if (!Depth[edge[i].to] && edge[i].Flow>0)
     48             {
     49                 Depth[edge[i].to]=Depth[x]+1;
     50                 Q[++Tail]=edge[i].to;
     51             }
     52     }
     53     if (Depth[e]>0) return true;
     54     return false;
     55 }
     56 
     57 int Dfs(int x,int low)
     58 {
     59     int Min,f=0;
     60     if (x==e || low==0)
     61         return low;
     62     for (int i=head[x];i!=0;i=edge[i].next)
     63         if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to , min(low,edge[i].Flow) )))
     64         {
     65             edge[i].Flow-=Min;
     66             edge[((i-1)^1)+1].Flow+=Min;
     67             f+=Min;
     68             low-=Min;
     69         }
     70     return f;
     71 }
     72 
     73 int Dinic(int s,int e)
     74 {
     75 //    int Ans=0;
     76     while (Bfs(s,e))
     77             Ans+=Dfs(s,0x7fffffff);
     78     return Ans;
     79 }
     80 
     81 void DISTANCE(int x,int y)
     82 {
     83     int Head=0,Tail=1;
     84     memset(used,false,sizeof(used));
     85     q[1][1]=x;
     86     q[1][2]=y;
     87     used[x][y]=true;
     88     while (Head<Tail)
     89     {
     90         ++Head;
     91         for (int i=1;i<=4;++i)
     92         {
     93             int xx=q[Head][1]+dx[i];
     94             int yy=q[Head][2]+dy[i];
     95             if (!used[xx][yy] && a[xx][yy])
     96             {
     97                 used[xx][yy]=true;
     98                 dis[num[x][y]][num[xx][yy]]=dis[num[x][y]][num[q[Head][1]][q[Head][2]]]+1;
     99                 q[++Tail][1]=xx;
    100                 q[Tail][2]=yy;
    101             }
    102         }    
    103     }
    104 }
    105 
    106 int main()
    107 {
    108     memset(&INF,0x7f,sizeof(INF));
    109     int n,m,cnt=0;
    110     scanf("%d%d",&n,&m);
    111     for (int i=1;i<=n;++i)
    112     {
    113         scanf("%s",ch);
    114         for (int j=1;j<=m;++j)
    115         {
    116             if (ch[j-1]=='X')
    117                 continue;
    118             num[i][j]=++cnt;
    119             if (ch[j-1]=='.')
    120             {
    121                 a[i][j]=1;
    122                 PEOPLE[++P_sum]=num[i][j];
    123             }
    124             else
    125             {
    126                 a[i][j]=2;
    127                 DOOR[++D_sum]=num[i][j];
    128             }
    129         }
    130     }
    131     for (int i=1;i<=n;++i)
    132         for (int j=1;j<=m;++j)
    133             if (a[i][j])
    134                 DISTANCE(i,j);
    135     for (int i=1;i<=P_sum;++i)
    136     {
    137         bool flag=false;
    138         for (int j=1;j<=D_sum;++j)
    139             if (dis[PEOPLE[i]][DOOR[j]]!=0)
    140             {
    141                 flag=true;
    142                 break;
    143             }
    144         if (!flag)
    145         {
    146             printf("impossible
    ");
    147             return 0;
    148         }
    149     }
    150     for (int i=1;i<=P_sum;++i)
    151     {
    152         add(0,PEOPLE[i],1);
    153         add(PEOPLE[i],0,0);
    154     }
    155     for (int i=1;i<=99999999;++i)
    156     {
    157         for (int j=1;j<=D_sum;++j)
    158         {
    159             add(DOOR[j],999,1);
    160             add(999,DOOR[j],0);
    161         }
    162         for (int j=1;j<=P_sum;++j)
    163             for (int k=1;k<=D_sum;++k)
    164                 if (dis[PEOPLE[j]][DOOR[k]]==i)
    165                 {
    166                     add(PEOPLE[j],DOOR[k],1);
    167                     add(DOOR[k],PEOPLE[j],0);
    168                 }
    169         if (Dinic(0,999)==P_sum)
    170         {
    171             printf("%d",i);
    172             return 0;
    173         }
    174     }
    175 }
  • 相关阅读:
    RedissonConfProperty
    IdGenerator(雪花)
    Btrace和arthas地址
    SqlFilter
    AuthorityFilter
    111
    分布式数据库-杂记
    站点集群
    分布式精华文章
    高并发
  • 原文地址:https://www.cnblogs.com/refun/p/8678685.html
Copyright © 2020-2023  润新知