zoukankan      html  css  js  c++  java
  • [bzoj1189]紧急疏散

    二分答案+判定,对于一个答案,源点向每一个点连一条流量为1的边,每一扇门向汇点连一条流量为时间的边,每一个人向每一个在答案时间内能走到的门连一条流量为1的边,跑最大流并判断流量是否等于人数。

    然而自从bzoj新增数据后就跑不过了,原因是不能保证有一组最优撤离方案使得在最后一个时刻以前(最后一个时刻可能人不够),每一扇门每一个时刻都有人出去(具体数据见bzoj讨论板)。

    可以对门拆为时间个点,每一个点向它到某扇门的最早时间以后每一个时刻的门连一条流量为1的边,每一个门现在只有1的流量,再跑网络流即可(只要开40000个点和5000000条边即可,当然最坏的点数/边数要比这个大)。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 50005
      4 #define id i*m+j+1
      5 struct ji{
      6     int nex,to,len;
      7 }edge[N*100];
      8 queue<int>q;
      9 int E,T,n,m,pe,head[N],work[N],d[N],vis[405][405],bh[405][41];
     10 char s[31][31];
     11 void add(int x,int y,int z){
     12     edge[E].nex=head[x];
     13     edge[E].to=y;
     14     edge[E].len=z;
     15     head[x]=E++;
     16     if (E&1)add(y,x,0);
     17 }
     18 bool bfs(int k){
     19     memset(d,-1,sizeof(d));
     20     q.push(k);
     21     d[k]=0;
     22     while (!q.empty()){
     23         k=q.front();
     24         q.pop();
     25         for(int i=head[k];i!=-1;i=edge[i].nex)
     26             if ((edge[i].len)&&(d[edge[i].to]<0)){
     27                 d[edge[i].to]=d[k]+1;
     28                 q.push(edge[i].to);
     29             }
     30     }
     31     return d[T]>=0;
     32 }
     33 int dfs(int k,int s){
     34     if (k==T)return s;
     35     for(int &i=work[k];i!=-1;i=edge[i].nex)
     36         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
     37             int p=dfs(edge[i].to,min(s,edge[i].len));
     38             if (p){
     39                 edge[i].len-=p;
     40                 edge[i^1].len+=p;
     41                 return p;
     42             }
     43         }
     44     return 0;
     45 }
     46 int dinic(){
     47     int k,ans=0;
     48     while (bfs(0)){
     49         memcpy(work,head,sizeof(head));
     50         while (k=dfs(0,0x3f3f3f3f))ans+=k;
     51     }
     52     return ans;
     53 }
     54 bool pd(int mid){
     55     memset(head,-1,sizeof(head));
     56     E=0;
     57     for(int i=0;i<n;i++)
     58         for(int j=0;j<m;j++){
     59             if (s[i][j]=='.'){
     60                 add(0,id,1);
     61                 for(int k=0;k<n*m;k++)
     62                     if (s[k/m][k%m]=='D')
     63                         for(int l=vis[id][k];l<=mid;l++)add(id,bh[k+1][l],1);
     64             }
     65             if (s[i][j]=='D')
     66                 for(int k=1;k<=mid;k++)add(bh[id][k],T,1);
     67         }
     68     return dinic()==pe;
     69 }
     70 int main(){
     71     scanf("%d%d",&n,&m);
     72     memset(head,-1,sizeof(head));
     73     for(int i=0;i<n;i++)scanf("%s",s[i]);
     74     for(int i=0;i<n;i++)
     75         for(int j=0;j<m;j++)
     76             if (s[i][j]!='X'){
     77                 if ((j)&&(s[i][j-1]!='X')&&((s[i][j-1]!='D')||(s[i][j]!='D')))add(id,id-1,1);
     78                 if ((j<m-1)&&(s[i][j+1]!='X')&&((s[i][j+1]!='D')||(s[i][j]!='D')))add(id,id+1,1);
     79                 if ((i)&&(s[i-1][j]!='X')&&((s[i-1][j]!='D')||(s[i][j]!='D')))add(id,id-m,1);
     80                 if ((i<n-1)&&(s[i+1][j]!='X')&&((s[i+1][j]!='D')||(s[i][j]!='D')))add(id,id+m,1);
     81             }
     82     for(int i=0;i<n;i++)
     83         for(int j=0;j<m;j++)
     84             if (s[i][j]=='.'){
     85                 bfs(id);
     86                 pe++;
     87                 for(int k=1;k<=n*m;k++)
     88                     if (d[k]==-1)vis[id][k-1]=10000;
     89                     else vis[id][k-1]=d[k];
     90             }
     91     T=n*m+1;
     92     for(int i=0;i<n;i++)
     93         for(int j=0;j<m;j++)
     94             if (s[i][j]=='D')
     95                 for(int k=1;k<=pe;k++)bh[id][k]=T++;
     96     int l=0,r=pe+1;
     97     while (l<r){
     98         int mid=(l+r>>1);
     99         if (pd(mid))r=mid;
    100         else l=mid+1;
    101     }
    102     if (l>pe)printf("impossible");
    103     else printf("%d",l);
    104 }
    View Code
  • 相关阅读:
    面向对象编程
    面向对象编程进阶
    pycharm常用快捷键
    面向对象
    深拷贝和浅拷贝
    hashlib模块
    日志配置
    常用模块大全
    正则详解
    软件目录规范
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11248468.html
Copyright © 2011-2022 走看看