• [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
  • 相关阅读:
    看了关于全职女性的文字,我想到了一些事情
    通过一个大型项目来学习分布式算法(6)
    IO模式——同步(堵塞、非堵塞)、异步
    湖南省第九届大学生计算机程序设计竞赛 高桥和低桥
    为什么我的ECSHOP出现报错改正确了还是没有反应?
    wxWidgets刚開始学习的人导引(2)——下载、安装wxWidgets
    1096. Consecutive Factors (20)
    POJ 2955 Brackets
    (转载)单调栈题目总结
    20140708郑州培训第二题Impossible Game
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11248468.html
Copyright © 2020-2023  润新知