码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1189: [HNOI2007]紧急疏散evacuate

时间:2014-12-20 20:50:09      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:

题解:

刚开始一直在想堵在一块儿的情况怎么办?发现不会。。。

结果看题解发现不用考虑T_T http://blog.sina.com.cn/s/blog_76f6777d01015ogm.html

代码:调的蛋疼。。。

技术分享
  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]==0||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 }
View Code

1189: [HNOI2007]紧急疏散evacuate

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 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

Sample Output

3

BZOJ1189: [HNOI2007]紧急疏散evacuate

标签:

原文地址:http://www.cnblogs.com/zyfzyf/p/4175791.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!