3566 紧急疏散

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold

题目描述 Description

发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是'.',那么表示这是一块空地;如果是'X',那么表示这是一面墙,如果是'D',那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。

输入描述 Input Description

输入文件第一行是由空格隔开的一对正整数N与M,3<=N <=20,3<=M<=20,以下N行M列描述一个N M的矩阵。其中的元素可为字符'.'、'X'和'D',且字符间无空格。

输出描述 Output Description

只有一个整数K,表示让所有人安全撤离的最短时间,如果不可能撤离,那么输出'impossible'(不包括引号).

样例输入 Sample Input

5 5  
XXXXX
X...D
XX.XX
X..XX
XXDXX

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

3<=N <=20,3<=M<=20

题解:

 对于每个门进行一次bfs,得出每个点到每个门的时间
 然后二分时间,每次建图dinic
 S到空地连一条容量1的边,
 每个空地到可到达的门连一条容量1的边,
 每个门到T连一条容量为时间的边

代码:

(对于codevs来说):

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define INF 0x7fffffff
  7 #define maxn 1001
  8 #define S 0
  9 #define T 1000
 10
 11 using namespace std;
 12
 13 int n,m,head[maxn],dis[401][21][21],ans,tot,cnt=1,door=1,layered[maxn],map[21][21],finallyans=-1;
 14 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
 15
 16 struct ss
 17    {
 18         int x;
 19         int y;
 20         int s;
 21         ss() {};
 22         ss(int a,int b,int c)
 23           {
 24                 x=a;
 25                 y=b;
 26                 s=c;
 27           };
 28    };
 29
 30 struct node
 31    {
 32         int to;
 33      int next;
 34      int edge;
 35    }e[1000001];
 36
 37 void add(int u,int v,int c)
 38   {
 39       e[++cnt].to=v;
 40       e[cnt].next=head[u];
 41       e[cnt].edge=c;
 42       head[u]=cnt;
 43   }
 44
 45 void insert(int u,int v,int c)
 46    {
 47      add(u,v,c);
 48      add(v,u,0);
 49    }
 50
 51 bool bfs()
 52    {
 53         for (int i=1;i<=T;i++) layered[i]=INF;
 54         queue<int>que;
 55         que.push(S);
 56         while (!que.empty())
 57            {
 58               int now=que.front();
 59            que.pop();
 60            for (int i=head[now];i;i=e[i].next)
 61              if (e[i].edge&&layered[e[i].to]>layered[now]+1)
 62                {
 63                    layered[e[i].to]=layered[now]+1;
 64                    que.push(e[i].to);
 65                    if (e[i].to==T) return 1;
 66                        }
 67            }
 68     return 0;
 69    }
 70
 71 int dfs(int x,int inf)
 72    {
 73         if (x==T) return inf;
 74         int rest=inf;
 75         for (int i=head[x];i&&rest;i=e[i].next)
 76            if (e[i].edge&&layered[e[i].to]==layered[x]+1)
 77              {
 78                 int now=dfs(e[i].to,min(rest,e[i].edge));
 79                 if (!layered[now]) layered[now]=0;
 80                 e[i].edge-=now;
 81                 e[i^1].edge+=now;
 82                 rest-=now;
 83             }
 84      return inf-rest;
 85     }
 86
 87 int dinic()
 88     {
 89         int ansn=0;
 90         while (bfs()) ansn+=dfs(S,INF);
 91         return ansn;
 92     }
 93
 94 void built(int x)
 95     {
 96       memset(head,0,sizeof (head));
 97       cnt=1;
 98       for (int i=1;i<=n;i++)
 99          for (int j=1;j<=m;j++)
100              if (map[i][j]==1)
101                {
102                  int v=(i-1)*m+j;
103                  insert(S,v,1);
104                }
105      for (int i=2;i<=door;i++)    insert(n*m+i,T,x);
106      for (int i=2;i<=door;i++)
107         for (int j=1;j<=n;j++)
108            for (int k=1;k<=m;k++)
109               if (dis[i][j][k]<=x) insert((j-1)*m+k,n*m+i,x);
110     }
111
112 bool judge(int x)
113     {
114       built(x);
115       int ans=dinic();
116       if (ans==tot) return 1;
117           else return 0;
118     }
119
120 void search(int k,int x,int y)
121     {
122         queue<ss>que;
123         que.push(ss(x,y,0));
124         while (!que.empty())
125            {
126                 for (int i=0;i<4;i++)
127                 {
128                   int nowx=que.front().x+xx[i];
129                   int nowy=que.front().y+yy[i];
130                   int s=que.front().s;
131                   if(nowx<1||nowy<1||nowx>n||nowy>m||map[nowx][nowy]!=1)    continue;
132                   if (dis[k][nowx][nowy]==INF)
133                       {
134                           dis[k][nowx][nowy]=s+1;
135                           que.push(ss(nowx,nowy,s+1));
136                       }
137                 }
138                 que.pop();
139            }
140     }
141 int main()
142     {
143        char ch[100];
144        scanf("%d%d",&n,&m);
145        for (int i=1;i<=n;i++)
146           {
147             scanf("%s",ch);
148             for (int j=1;j<=m;j++)
149               {
150                  if (ch[j-1]=='.') map[i][j]=1,tot++;
151                  if (ch[j-1]=='D') map[i][j]=++door;
152                }
153           }
154        for (int i=2;i<=door;i++)
155           for (int j=1;j<=n;j++)
156              for (int k=1;k<=m;k++)
157                  dis[i][j][k]=INF;
158        for (int i=1;i<=n;i++)
159           for (int j=1;j<=m;j++)
160              if (map[i][j]>1) search(map[i][j],i,j);
161        int l=0,r=400;
162        while (l<=r)
163          {
164            int mid=(l+r)>>1;
165            if (judge(mid)) finallyans=r=mid,r--;
166              else l=mid+1;
167          }
168        if (finallyans==-1) printf("impossible");
169            else printf("%d",finallyans);
170        return 0;
171        }                                        

对于bzoj来说:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 #define mid (l+r)/2
  6 #define inf 0x7fffffff
  7 #define T n*n*m*m+2
  8 const int N=30;
  9 const int M=200000;
 10 char s[N];
 11 bool use[N][N],flag[N][N];
 12 struct S{int x,y,c;}l[N*N];
 13 struct Q{int st,en,va;}aa[M*2];
 14 int n,m,map[N][N],f[N][N][N][N],sum,point[M],next[M*2],cur[M],dis[M],pre[M],gap[M],tot;
 15 int xi[4]={-1,0,0,1},yi[4]={0,-1,1,0};
 16 inline void bfs(int xa,int ya){
 17     int i,h,t,k,x,y;
 18     memset(use,1,sizeof(use));
 19     h=t=1;l[h].x=xa;l[h].y=ya;l[h].c=0;
 20     while(h<=t){
 21         x=l[h].x;y=l[h].y;
 22         for(i=0;i<4;++i){
 23             int xx=x+xi[i],yy=y+yi[i];
 24             if(xx>0&&xx<=n&&yy>0&&y<=m&&map[xx][yy]==1&&use[xx][yy]){
 25                 l[++t].x=xx;l[t].y=yy;l[t].c=l[h].c+1;
 26                 use[xx][yy]=false;
 27                 f[xx][yy][xa][ya]=l[t].c;
 28                 flag[xx][yy]=true;
 29             }
 30         }
 31         h+=1;
 32     }
 33 }
 34 inline void add(int x,int y,int z){
 35     tot+=1;next[tot]=point[x];point[x]=tot;
 36     aa[tot].st=x;aa[tot].en=y;aa[tot].va=z;
 37     tot+=1;next[tot]=point[y];point[y]=tot;
 38     aa[tot].st=y;aa[tot].en=x;aa[tot].va=0;
 39 }
 40 inline int ISAP(int ss,int tt){
 41     bool f;
 42     int minn,ans=0,i,u,y;
 43     memset(dis,0,sizeof(dis));
 44     memset(gap,0,sizeof(gap));
 45     memset(pre,0,sizeof(pre));
 46     gap[0]=tt-ss+1; u=ss;
 47     for(i=ss;i<=tt;++i) cur[i]=point[i];
 48     while(dis[ss]<tt-ss+1){
 49         f=false;
 50         for(i=cur[u];i;i=next[i])
 51           if(aa[i].va>0&&dis[u]==dis[aa[i].en]+1){
 52             cur[u]=i;f=true;break;
 53           }
 54         if(f){
 55             pre[u=aa[i].en]=i;
 56             if(u==tt){
 57                 minn=inf;
 58                 for(i=u;i!=ss;i=aa[pre[i]].st)
 59                   minn=min(minn,aa[pre[i]].va);
 60                 ans+=minn;
 61                 for(i=u;i!=ss;i=aa[pre[i]].st){
 62                     aa[pre[i]].va-=minn;
 63                     aa[pre[i]^1].va+=minn;
 64                 }
 65                 u=ss;
 66             }
 67         }
 68         else{
 69             --gap[dis[u]];
 70             if(!gap[dis[u]]) return ans;
 71             y=2*tt; cur[u]=point[u];
 72             for(i=point[u];i;i=next[i])
 73               if(aa[i].va>0) y=min(y,dis[aa[i].st]);
 74             ++gap[dis[u]=y+1];
 75             if(u!=ss) u=aa[pre[u]].st;
 76         }
 77     }
 78     return ans;
 79 }
 80 inline bool check(int x){
 81     int i,j,p,q;
 82     tot=1;
 83     memset(point,0,sizeof(point));
 84     memset(next,0,sizeof(next));
 85     for(i=1;i<=n;++i)
 86       for(j=1;j<=m;++j){
 87         int now=((i-1)*m+j-1)*n*m;
 88         if(map[i][j]==0){
 89             for(p=1;p<x;++p)
 90               add(now+p+1,now+p+2,inf),add(now+p+1,T,1);
 91             add(now+x+1,T,1);
 92         }
 93         if(map[i][j]==1){
 94             add(1,now+1,1);
 95             for(p=1;p<=n;++p)
 96               for(q=1;q<=m;++q)
 97                 if(f[i][j][p][q])
 98                   add(now+1,((p-1)*m+q-1)*n*m+f[i][j][p][q]+1,1);
 99         }
100       }
101     return ISAP(1,T)==sum;
102 }
103 int main(){
104     int i,j;
105     scanf("%d%d",&n,&m);
106     for(i=1;i<=n;++i){
107         scanf("%s",&s);
108         for(j=0;j<m;++j){
109             if(s[j]=='D') map[i][j+1]=0;
110             if(s[j]=='.') map[i][j+1]=1,sum+=1;
111             if(s[j]=='X') map[i][j+1]=2;
112         }
113     }
114     for(i=1;i<=n;++i)
115       for(j=1;j<=m;++j)
116         if(map[i][j]==0)
117           bfs(i,j);
118     for(i=1;i<=n;++i)
119       for(j=1;j<=m;++j)
120         if(!flag[i][j]&&map[i][j]==1){
121             printf("impossible\n");
122             return 0;
123         }
124     int l=1,r=n*m,ans=inf;
125     while(l<r){
126         if(check(mid)) ans=min(ans,mid),r=mid;
127         else l=mid+1;
128     }
129     printf("%d\n",ans);
130 }

转载于:https://www.cnblogs.com/grhyxzc/p/5211111.html

C++之路进阶——codevs3566(紧急疏散)相关推荐

  1. 音视频开发成长之路—进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频

    音视频开发成长之路-进阶之路3个重要知识点 视频讲解如下,点击观看: 音视频开发成长之路-进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频 音视频高级 ...

  2. Java成神之路-进阶步骤(转)

    https://www.hollischuang.com/archives/3280 一.基础篇 面向对象 什么是面向对象 面向对象.面向过程 面向对象的三大基本特征和五大基本原则 平台无关性 Jav ...

  3. C++之路进阶codevs1242(布局)

    1242 布局 2005年USACO  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold  <:section class="hbox"& ...

  4. C++之路进阶——codevs2313(星际竞速)

    2313 星际竞速 2010年省队选拔赛山东  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述  Description 10 年一度的银河系赛车大 ...

  5. C++之路进阶——bzoj1821(部落划分)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser   hyxzc Logout 捐赠本站 Notice:1:由于本OJ ...

  6. 网络工程师的python之路pdf_网络工程师的Python之路---Ansible篇

    版权声明:我已加入"维权骑士"(http://rightknights.com)的版权保护计划,所有知乎专栏"网路行者"下的文章均为我本人(知乎ID:弈心)原创 ...

  7. 从新手到专家 ——外包团队研发工程师的成长之路

    大多数选择从事外包的研发人员更多的是看中外包中高薪资.在外包团队中,研发人员如何快速提升个人的价值?在团队中赢得其他同事的尊重.在物质上获取更大的回报?是我们每一个外包从业者需要思考的问题. 外包企业 ...

  8. 底层框架_你有必要了解一下Flink底层RPC使用的框架和原理

    1. 前言 对于Flink中各个组件(JobMaster.TaskManager.Dispatcher等),其底层RPC框架基于Akka实现,本文着重分析Flink中的Rpc框架实现机制及梳理其通信流 ...

  9. linux装windows报错,安装Windows 和 Linux双系统(vmware) Centos7

    这里我安装的是Windows + Centos 7,如果是要安装Centos 6,步骤一样 一.安装Windows和Linux双系统需要先安装Windows然后安装Linux 解释:这里解释下为什么要 ...

最新文章

  1. python 调用api上传物流信息,python实现快递鸟API物流查询接口 数据签名方法
  2. 后盾网lavarel视频项目---3、lavarel中子控制器继承父控制器以判断是否登录
  3. BugkuCTF–flag在index里
  4. 设置eclipse中的编辑区的背景颜色、注释文字的颜色、修改注释内作者名和时间
  5. koa --- koa-bouncer验证
  6. Spring中@Autowired、@Qualifier、@Resource的区别
  7. 苹果Apple Watch样机Mockups素材,你用过吗?
  8. OpenCasCade网格的显示
  9. Step05:爬虫小项目,爬取最新电影迅雷下载地址
  10. WINDOWS操作系统发展历程
  11. 虎克哈克环槽铆钉机 铆接回收机振动筛设备 钢结构集装箱铆接机
  12. 删除指定位置的元素(数组)(PTA)
  13. 追风人拍到壮观龙卷风
  14. 前端面试题(react)
  15. WP响应式平扁设计风格Uigreat V1.5.1主题 源代码
  16. 「面试」给金融科技安排明白了
  17. 意大利CEMB一款经济振动现场动平衡仪
  18. 虹科分享 | CANopen协议基础知识——LSS服务
  19. 访问学者的推荐信要注意这4点?
  20. AD9361 补充(上)

热门文章

  1. 正数的原码,反码,补码
  2. 彻底弄清补码加减法运算,正数、负数位移运算原理
  3. VMware workstation虚拟机REHL8下配置安装Django 4.0.6 +uwsgi 2.0.20 +nginx1.22+Mariadb10.9.1
  4. 深入理解机器学习中的:目标函数,损失函数和代价函数
  5. 4pin oled字模,oled图片编码生成方法
  6. fatal unable to auto-detect email address (got ‘...@...(none)‘)
  7. 如何在网页端登录企业邮箱修改密码?
  8. 卷积 对图像进行卷积操作 卷积神经网络
  9. 百度wenku的下载
  10. [935]python解析xml文件