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\n",mn); 160 return 0; 161 }
网络流 先进行dfs 记入空地到每个门的时间 二分时间,建边判断是否满流,新加了数据,要对门按时间进行拆点