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
原文地址:https://www.cnblogs.com/zyfzyf/p/4175791.html