• bzoj 1189: [HNOI2007]紧急疏散evacuate


      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define inf 0x7fffffff
      5 #define M 5000008
      6 #define N 161000
      7 using namespace std;
      8 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
      9 int map[21][21],n,m,D=1,a[410][22][22],q[1010][3],ans,cnt,head[N],next[M],u[M],v[M],T,tot,d1[N],q1[2*N];
     10 char ch[50];
     11 void zhao(int a1,int a2,int a3)
     12 {
     13     int h=0,t=1;
     14     q[1][0]=a2;
     15     q[1][1]=a3;
     16     q[1][2]=0;
     17     for(;h<t;)
     18       {
     19         h++;
     20         for(int i=0;i<4;i++)
     21           {
     22             int nx=q[h][0]+xx[i],ny=q[h][1]+yy[i];
     23             if(!nx||nx>n||!ny||ny>m||map[nx][ny]!=1)
     24               continue;
     25             if(a[a1][nx][ny]==inf)
     26               {
     27                 t++;
     28                 a[a1][nx][ny]=q[t][2]=q[h][2]+1;
     29                 q[t][0]=nx;
     30                 q[t][1]=ny;
     31               }
     32           }
     33       }
     34     return;
     35 }
     36 void jia(int a1,int a2,int a3)
     37 {
     38     cnt++;
     39     u[cnt]=a2;
     40     v[cnt]=a3;
     41     next[cnt]=head[a1];
     42     head[a1]=cnt;
     43     return;
     44 }
     45 bool bfs()
     46 {
     47     memset(d1,0,sizeof(int)*(T+1));
     48     int h=0,t=1;
     49     q1[1]=0;
     50     d1[0]=1;
     51     for(;h<t;)
     52       {
     53         h++;
     54         int p=q1[h];
     55         for(int i=head[p];i;i=next[i])
     56           if(!d1[u[i]]&&v[i])
     57             {
     58                 d1[u[i]]=d1[p]+1;
     59                 if(d1[T])
     60                   return 1;
     61                 t++;
     62                 q1[t]=u[i];
     63             }
     64       }
     65     return 0;
     66 }
     67 int dinic(int s,int f)
     68 {
     69     if(s==T)
     70       return f;
     71     int rest=f;
     72     for(int i=head[s];i&&rest;i=next[i])
     73       if(v[i]&&d1[u[i]]==d1[s]+1)
     74         {
     75             int now=dinic(u[i],min(rest,v[i]));
     76             if(!now)
     77               d1[u[i]]=0;
     78             v[i]-=now;
     79             v[i^1]+=now;
     80             rest-=now;
     81         }
     82     return f-rest;  
     83 }
     84 bool pan(int a1)
     85 {
     86     memset(head,0,sizeof(int)*(T+1));
     87     cnt=1;
     88     for(int i=1;i<=n;i++)
     89       for(int j=1;j<=m;j++)
     90         if(map[i][j]==1)
     91           {
     92             jia(0,(i-1)*m+j,1);
     93             jia((i-1)*m+j,0,0);
     94           }
     95     for(int k=2;k<=D;k++)
     96       for(int i=1;i<=n;i++)
     97         for(int j=1;j<=m;j++)
     98           if(a[k][i][j]!=inf)
     99            for(int l=1;l<=a1;l++)
    100             if(a[k][i][j]<=l)
    101               {
    102                 jia((i-1)*m+j,n*m+D*(l-1)+k,1);
    103                 jia(n*m+D*(l-1)+k,(i-1)*m+j,0);
    104               }
    105     for(int k=2;k<=D;k++)
    106       for(int l=1;l<=a1;l++)
    107       {
    108         jia(n*m+D*(l-1)+k,T,1);
    109         jia(T,n*m+D*(l-1)+k,0);
    110       }
    111     ans=0;
    112     for(;bfs();)
    113       ans+=dinic(0,inf);
    114     if(ans==tot)
    115       return 1;
    116     return 0;
    117 }
    118 int main()
    119 {
    120     scanf("%d%d",&n,&m);
    121     for(int i=1;i<=n;i++)
    122       {
    123         scanf("%s",ch+1);
    124         for(int j=1;j<=m;j++)
    125           {
    126             if(ch[j]=='.')
    127               {
    128                 map[i][j]=1;
    129                 tot++;
    130               }
    131             if(ch[j]=='D')
    132               map[i][j]=++D;
    133           }
    134       }
    135     T=160010;
    136     for(int k=2;k<=D;k++)
    137       for(int i=1;i<=n;i++)
    138         for(int j=1;j<=m;j++)
    139           a[k][i][j]=inf;
    140     for(int i=1;i<=n;i++)
    141       for(int j=1;j<=m;j++)
    142         if(map[i][j]>1)
    143           zhao(map[i][j],i,j);
    144     int l=0,r=400,mn=-1;
    145     for(;l<=r;)
    146       {
    147         int mid=(l+r)>>1;
    148         if(pan(mid))
    149           {
    150             mn=mid;
    151             r=mid-1;
    152           }
    153         else
    154           l=mid+1;
    155       }
    156     if(mn==-1)
    157       printf("impossible");
    158     else
    159       printf("%d
    ",mn);
    160     return 0;
    161 }

    网络流 先进行dfs 记入空地到每个门的时间 二分时间,建边判断是否满流,新加了数据,要对门按时间进行拆点

  • 相关阅读:
    find命令
    shell编程基础
    grep命令
    awk命令
    结对项目之需求分析与原型模型设计
    使用Git进行代码管理的心得
    软件工程的实践项目的自我目标
    第五次作业——团队项目——需求规格说明书
    调研android开发环境的发展演变
    结对编程总结
  • 原文地址:https://www.cnblogs.com/xydddd/p/5240423.html
Copyright © 2020-2023  润新知