BZOJ1189: [HNOI2007]紧急疏散evacuate
题解:
刚开始一直在想堵在一块儿的情况怎么办?发现不会。。。
结果看题解发现不用考虑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 }
下面的代码有错 欢迎查错
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 500+5 14 #define maxm 100000 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next) 23 #define mod 1000000007 24 using namespace std; 25 inline int read() 26 { 27 int x=0,f=1;char ch=getchar(); 28 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 29 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 30 return x*f; 31 } 32 int n,m,s,t,cnt,maxflow,tot=1,head[maxn],cur[maxn],h[maxn],c[maxn][maxn],num[maxn][maxn]; 33 int d[25][25][25][25]; 34 struct edge{int go,next,v;}e[maxm]; 35 void ins(int x,int y,int z){e[++tot].go=y;e[tot].v=z;e[tot].next=head[x];head[x]=tot;} 36 void insert(int x,int y,int z){ins(x,y,z);ins(y,x,0);} 37 queue<int>q; 38 bool bfs() 39 { 40 for(int i=s;i<=t;i++)h[i]=-1; 41 q.push(s);h[s]=0; 42 while(!q.empty()) 43 { 44 int x=q.front();q.pop(); 45 for(int i=head[x];i;i=e[i].next) 46 if(e[i].v&&h[e[i].go]==-1) 47 { 48 h[e[i].go]=h[x]+1;q.push(e[i].go); 49 } 50 } 51 return h[t]!=-1; 52 } 53 int dfs(int x,int f) 54 { 55 if(x==t) return f; 56 int tmp,used=0; 57 for(int i=cur[x];i;i=e[i].next) 58 if(e[i].v&&h[e[i].go]==h[x]+1) 59 { 60 tmp=dfs(e[i].go,min(e[i].v,f-used)); 61 e[i].v-=tmp;if(e[i].v)cur[x]=i; 62 e[i^1].v+=tmp;used+=tmp; 63 if(used==f)return f; 64 } 65 if(!used) h[x]=-1; 66 return used; 67 } 68 void dinic() 69 { 70 maxflow=0; 71 while(bfs()) 72 { 73 for (int i=s;i<=t;i++)cur[i]=head[i];maxflow+=dfs(s,inf); 74 } 75 } 76 bool check(int x) 77 { 78 memset(head,0,sizeof(head));tot=1; 79 for1(i,n)for1(j,m) 80 { 81 if(c[i][j]==1)insert(s,num[i][j],1); 82 if(c[i][j]==2)insert(num[i][j],t,x); 83 } 84 for1(i,n)for1(j,m)if(c[i][j]==1) 85 for1(ii,n)for1(jj,m)if(c[ii][jj]==2) 86 if(d[i][j][ii][jj]<=x)insert(num[i][j],num[ii][jj],1); 87 dinic(); 88 return maxflow==cnt; 89 } 90 queue<pa>qq; 91 bool v[maxn][maxn]; 92 const int dx[4]={0,1,-1,0}; 93 const int dy[4]={1,0,0,-1}; 94 int main() 95 { 96 freopen("input.txt","r",stdin); 97 freopen("output.txt","w",stdout); 98 n=read();m=read();s=0;t=n*m+1; 99 for1(i,n)for1(j,m)num[i][j]=(i-1)*m+j; 100 for1(i,n)for1(j,m) 101 { 102 char ch=getchar(); 103 while(ch!='X'&&ch!='D'&&ch!='.')ch=getchar(); 104 if(ch=='.')c[i][j]=1,cnt++; 105 else if(ch=='D')c[i][j]=2; 106 } 107 for1(i,n)for1(j,m)if(c[i][j]==1) 108 { 109 memset(v,0,sizeof(v));v[i][j]=1; 110 for1(x,n)for1(y,m)d[i][j][x][y]=inf; 111 d[i][j][i][j]=0; 112 qq.push(pa(i,j)); 113 while(!qq.empty()) 114 { 115 int x=qq.front().first,y=qq.front().second; 116 qq.pop(); 117 for0(k,3) 118 { 119 int xx=x+dx[k],yy=y+dy[k]; 120 if(xx<1||xx>n||yy<1||yy>m||c[xx][yy]!=1||v[xx][yy])continue; 121 v[xx][yy]=1;d[i][j][xx][yy]=d[i][j][x][y]+1; 122 qq.push(pa(xx,yy)); 123 } 124 } 125 } 126 int l=0,r=inf; 127 while(l<=r) 128 { 129 int mid=(l+r)>>1; 130 if(check(mid))r=mid-1;else l=mid+1; 131 } 132 if(l>=inf)printf("impossible\n");else printf("%d\n",l); 133 return 0; 134 }
1189: [HNOI2007]紧急疏散evacuate
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 693 Solved: 290
[Submit][Status]
Description
发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一块空地;如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。
Input
输入文件第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,以下N行M列描述一个N M的矩阵。其中的元素可为字符'.'、'X'和'D',且字符间无空格。
Output
只有一个整数K,表示让所有人安全撤离的最短时间,如果不可能撤离,那么输出'impossible'(不包括引号)。
Sample Input
5 5
XXXXX
X...D
XX.XX
X..XX
XXDXX
XXXXX
X...D
XX.XX
X..XX
XXDXX
Sample Output
3