题解:
刚开始一直在想堵在一块儿的情况怎么办?发现不会。。。
结果看题解发现不用考虑T_T http://blog.sina.com.cn/s/blog_76f6777d01015ogm.html
代码:调的蛋疼。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define S 0 5 #define T 1000 6 #define inf 0x7fffffff 7 using namespace std; 8 int n,m,door=1,cnt,ans,tot,mn=-1; 9 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; 10 int mp[21][21],head[1001],h[1001],q[1001]; 11 int dis[401][21][21]; 12 struct data{int x,y,s;}d[401]; 13 struct data2{int to,next,v;}e[1000001]; 14 bool bfs() 15 { 16 int t=0,w=1,i,now; 17 memset(h,-1,sizeof(h)); 18 h[S]=0;q[0]=S; 19 while(t<w) 20 { 21 now=q[t];t++; 22 i=head[now]; 23 while(i) 24 { 25 if(h[e[i].to]==-1&&e[i].v){h[e[i].to]=h[now]+1;q[w++]=e[i].to;} 26 i=e[i].next; 27 } 28 } 29 if(h[T]==-1)return 0; 30 return 1; 31 } 32 int dfs(int x,int f) 33 { 34 if(x==T)return f; 35 int i=head[x]; 36 int w,used=0; 37 while(i) 38 { 39 if(e[i].v&&h[e[i].to]==h[x]+1) 40 { 41 w=f-used; 42 w=dfs(e[i].to,min(w,e[i].v)); 43 e[i].v-=w; 44 e[i^1].v+=w; 45 used+=w; 46 if(used==f)return f; 47 } 48 i=e[i].next; 49 } 50 if(!used)h[x]=-1; 51 return used; 52 } 53 void dinic(){while(bfs())ans+=dfs(0,inf);} 54 void ins(int u,int v,int w) 55 {e[++cnt].to=v;e[cnt].next=head[u];e[cnt].v=w;head[u]=cnt;} 56 void insert(int u,int v,int w) 57 {ins(u,v,w);ins(v,u,0);} 58 void build(int x) 59 { 60 memset(head,0,sizeof(head)); 61 cnt=1; 62 for(int i=1;i<=n;i++) 63 for(int j=1;j<=m;j++) 64 if(mp[i][j]==1)insert(S,(i-1)*m+j,1); 65 for(int i=2;i<=door;i++)insert(n*m+i,T,x); 66 for(int i=2;i<=door;i++) 67 for(int j=1;j<=n;j++) 68 for(int k=1;k<=m;k++) 69 if(dis[i][j][k]<=x)insert((j-1)*m+k,n*m+i,x); 70 } 71 void search(int k,int x,int y) 72 { 73 int t=0,w=1,nowx,nowy; 74 d[0].x=x;d[0].y=y; 75 while(t<w) 76 { 77 for(int i=0;i<4;i++) 78 { 79 nowx=d[t].x+xx[i],nowy=d[t].y+yy[i]; 80 if(nowx<1||nowy<1||nowx>n||nowy>m||mp[nowx][nowy]!=1)continue; 81 if(dis[k][nowx][nowy]==inf) 82 { 83 dis[k][nowx][nowy]=d[w].s=d[t].s+1; 84 d[w].x=nowx;d[w].y=nowy; 85 w++; 86 } 87 } 88 t++; 89 } 90 } 91 bool judge(int x) 92 { 93 build(x); 94 ans=0; 95 dinic(); 96 if(ans==tot)return 1; 97 return 0; 98 } 99 int main() 100 { 101 scanf("%d%d",&n,&m); 102 char ch[21]; 103 for(int i=1;i<=n;i++) 104 { 105 scanf("%s",ch); 106 for(int j=1;j<=m;j++) 107 { 108 if(ch[j-1]=='.'){mp[i][j]=1;tot++;} 109 else if(ch[j-1]=='D')mp[i][j]=++door; 110 } 111 } 112 for(int i=2;i<=door;i++) 113 for(int j=1;j<=n;j++) 114 for(int k=1;k<=m;k++) 115 dis[i][j][k]=inf; 116 for(int i=1;i<=n;i++) 117 for(int j=1;j<=m;j++) 118 if(mp[i][j]>1)search(mp[i][j],i,j); 119 int l=0,r=400; 120 while(l<=r) 121 { 122 int mid=(l+r)>>1; 123 if(judge(mid)){mn=mid;r=mid-1;} 124 else l=mid+1; 125 } 126 if(mn==-1)printf("impossible"); 127 else printf("%d",mn); 128 return 0; 129 }