• hdu 1733 分层网络流 ****


    题目大意:有一个类似于迷宫搜索的图,‘.’代表的是无人的路,'X'代表有人的点,'#'代表此点不可通过,'@'代表门口。每个位置每一秒钟只能站一个人,每个位置到上下左右点的时间为1,问你所有人能不能出去,能出去输出所有人都出去的最小时间,否则输出-1.

    链接:点我

    A: 增加源点src,和汇点dest,然后根据每个时间点建出分层图,每个时间对应一层,对于每层图的构造如下

    B:给每个格子标 上号Xi, 由于每个格子一次只能占一人,所以把每个格子分为两个点xa,xb,连上容量为1的有向边,对于格子为‘X’的,(如果为第0层的话)在源点src与xa 之间连一条容量为1的有向边,对于格子为'@'的点,在xb与汇点dest连上容量为1的有向边,对于每个格子,(除‘#’外),在xb与其上下左右及其本身 的对应下一层图的xa连上容量为1 的一条有向边

    C:具体操作并不是一下子建出分层图,由于时间是未知的,所以枚举时间,做最大流,当最大流小于人数时,时间加一并在原图上增加一层,继续求最大流,直到最大流大于等于人数,这时的时间就是答案

    原理懂了,代码也懂了,真自己敲估计还是很难敲出来,等专题训练吧

      1 /*HDU_1733 Escape*/
      2 /*分层图网络流+枚举时间*/
      3 /*AC代码:171ms*/
      4 #include <iostream>
      5 #include <cstdio>
      6 #include <memory.h>
      7 #include <algorithm>
      8 #define MAXN 20005
      9 #define Lim 75
     10 #define INF (1<<30)
     11 #define max(a,b) (a>b?a:b)
     12 #define min(a,b) (a<b?a:b)
     13 using namespace std;
     14 struct Node
     15 {
     16     int x,y;
     17     Node(int x1,int y1)
     18     {x=x1;y=y1;}
     19     Node(){}
     20 };
     21 struct edge
     22 {
     23     int u,v,w,next;
     24 }E[2000000];
     25 int head[MAXN],ecnt;
     26 int gap[MAXN],cur[MAXN],dis[MAXN],pre[MAXN];
     27 int N,M,scr,sink,vn,Ti,Sum,now;
     28 int ans;
     29 int dir[5][2]={0,1,0,-1,1,0,-1,0,0,0};
     30 char map[20][20];
     31 Node Q[200000];
     32 int Head,Tail;
     33 bool vis[20][20];
     34 void Insert(int u,int v,int w)
     35 {
     36     E[ecnt].u=u;
     37     E[ecnt].v=v;
     38     E[ecnt].w=w;
     39     E[ecnt].next=head[u];
     40     head[u]=ecnt++;
     41     E[ecnt].u=v;
     42     E[ecnt].v=u;
     43     E[ecnt].w=0;
     44     E[ecnt].next=head[v];
     45     head[v]=ecnt++;
     46 }
     47 bool BFS(Node s)
     48 {
     49     int i,j;
     50     Node u,v;
     51     memset(vis,false,sizeof(vis));
     52     Head=Tail=0;
     53     vis[s.x][s.y]=true;
     54     Q[Head++]=s;
     55     while(Head!=Tail)
     56     {
     57         u=Q[Tail++];
     58         if(map[u.x][u.y]=='@') return true;
     59         for(i=0;i<4;i++)
     60         {
     61             int dx=u.x+dir[i][0];
     62             int dy=u.y+dir[i][1];
     63             if(dx>=0&&dx<N&&dy>=0&&dy<M&&map[dx][dy]!='#'&&!vis[dx][dy])
     64             {
     65                 vis[dx][dy]=true;
     66                 Q[Head++]=Node(dx,dy);
     67             }
     68         }
     69     }
     70     return false;
     71 }
     72 bool OK()
     73 {
     74     bool ok=true;
     75     Node s;
     76     int i,j;
     77     for(i=0;i<N&&ok;i++)
     78     {
     79         for(j=0;j<M;j++)
     80         {
     81             if(map[i][j]=='X')
     82             {
     83                 s.x=i;s.y=j;
     84                 if(!BFS(s))
     85                 {
     86                     ok=false;
     87                     break;
     88                 }
     89             }
     90         }
     91     }
     92     return ok;
     93 }
     94 void Init()
     95 {
     96     int i,j,u;
     97     memset(head,-1,sizeof(head));ecnt=0;
     98     for(i=0;i<N;i++)
     99         scanf("%s",map[i]);
    100     scr=0;sink=1;vn=2;
    101     Sum=0;
    102     for(i=0;i<N;i++)
    103     {
    104         for(j=0;j<M;j++)
    105         {
    106             if(map[i][j]=='X')
    107             {
    108                 Sum++;
    109                 u=i*M+j+2;
    110                 Insert(scr,u,1);
    111             }
    112         }
    113     }
    114     now=(M*N);
    115     vn+=now;
    116 }
    117 int Sap(int s,int t,int n)//核心代码(模版)
    118 {
    119     int ans=0,aug=INF;//aug表示增广路的流量
    120     int i,v,u=pre[s]=s;
    121     for(i=0;i<=n;i++)
    122     {
    123         cur[i]=head[i];
    124         dis[i]=gap[i]=0;
    125     }
    126     gap[s]=n;
    127     bool flag;
    128     while(dis[s]<n)
    129     {
    130         flag=false;
    131         for(int &j=cur[u];j!=-1;j=E[j].next)//一定要定义成int &j,why
    132         {
    133             v=E[j].v;
    134             if(E[j].w>0&&dis[u]==dis[v]+1)
    135             {
    136                 flag=true;//找到容许边
    137                 aug=min(aug,E[j].w);
    138                 pre[v]=u;
    139                 u=v;
    140                 if(u==t)
    141                 {
    142                     ans+=aug;
    143                     while(u!=s)
    144                     {
    145                         u=pre[u];
    146                         E[cur[u]].w-=aug;
    147                         E[cur[u]^1].w+=aug;//注意
    148                     }
    149                     aug=INF;
    150                 }
    151                 break;//找到一条就退出
    152             }
    153         }
    154         if(flag) continue;
    155         int mindis=n;
    156         for(i=head[u];i!=-1;i=E[i].next)
    157         {
    158             v=E[i].v;
    159             if(E[i].w>0&&dis[v]<mindis)
    160             {
    161                 mindis=dis[v];
    162                 cur[u]=i;
    163             }
    164         }
    165         if((--gap[dis[u]])==0) break;
    166         gap[dis[u]=mindis+1]++;
    167         u=pre[u];
    168     }
    169     return ans;
    170 }
    171 
    172 bool Judge(int Ti)
    173 {
    174     int i,j,k,u,v,a,b,dx,dy;
    175     for(i=0;i<N;i++)
    176     {
    177         for(j=0;j<M;j++)
    178         {
    179             if(map[i][j]=='#') continue;
    180             u=i*M+j+1;
    181             a=(Ti-1)*N*M;
    182             b=a+N*M;
    183             u=a+u+1;
    184             for(k=0;k<5;k++)
    185             {
    186                 dx=i+dir[k][0];
    187                 dy=j+dir[k][1];
    188                 if(dx>=0&&dx<N&&dy>=0&&dy<M&&map[dx][dy]!='#')
    189                 {
    190                     v=dx*M+dy+1;
    191                     v=b+v+1;
    192                     Insert(u,v,1);
    193                 }
    194             }
    195             if(map[i][j]=='@')
    196             {
    197                 v=b+i*M+j+2;
    198                 Insert(v,sink,1);
    199             }
    200         }
    201     }
    202     vn+=(N*M);
    203     now+=(N*M);         //这个now好像没啥用
    204     int t=Sap(scr,sink,vn);
    205     ans+=t;
    206     return ans==Sum;
    207 }
    208 void Solve()
    209 {
    210     if(Sum==0) {printf("0
    ");return;}
    211     if(!OK())  {printf("-1
    ");return;}
    212     ans=Ti=0;
    213     while(true)
    214     {
    215         Ti++;
    216         if(Judge(Ti)) break;
    217     }
    218     printf("%d
    ",Ti);
    219 }
    220 int main()
    221 {
    222     while(scanf("%d%d",&N,&M)!=EOF)
    223     {
    224         Init();
    225         Solve();
    226     }
    227 return 0;
    228 }
  • 相关阅读:
    The OpenGL pipeline
    HLS协议实现
    用C++设计一个不能被继承的类
    Ansible@一个高效的配置管理工具--Ansible configure management--翻译(八)
    史上最简单的软件破解——5行脚本代码完美破解99%的过期软件
    oracle11g创建新的用户和改动最大连接数
    【SICP感应】1 工艺和替代模式
    ant利用先进,ant订单具体解释,ant包,ant包装删除编译jar文件
    SqlServer表EXCEL数据复制的另一种方法
    【摘要干】如何执飞前写商业计划?
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4678891.html
Copyright © 2020-2023  润新知