zoukankan      html  css  js  c++  java
  • 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 }
    View Code

    下面的代码有错 欢迎查错

      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
    ");else printf("%d
    ",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
  • 相关阅读:
    赋值、浅拷贝以及深拷贝的区别
    Python实现工厂模式
    Python实现代理模式
    select监听udp消息
    awk词频统计
    Python正则的贪婪和非贪婪示例
    js配置文件不缓存
    jquery事件命名空间和css-attr()
    iso移动Safari页面缓存
    javaWeb禁止http不安全请求方式
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4175791.html
Copyright © 2011-2022 走看看