# [HNOI2007]紧急疏散evacuate

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

## Sample Output

3

solution
(ps：这题有两个SB的错误，结果调了一个晚上......）

S向各个人连 1 的边

1.这个点向每一个能到的门 都得连边！！！！！
2.存边数组又开小了

popoqqq大佬的数据

4 5
XXDXX
XX.XX
X...X
XXDXX

  1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #include<iostream>
5 #define mem(a,b) memset(a,b,sizeof(a))
6 #define ll long long
7 #define dd double
8 using namespace std;
9 const int INF=(1<<31)-1;
10 inline int maxn(int a,int b){return a>b?a:b;}
11 inline int minn(int a,int b){return a<b?a:b;}
13 {
14     char q=getchar();
15     while(q!='.'&&q!='X'&&q!='D')q=getchar();
16     return q;
17 }
18 struct son
19 {
20     int u,v,next,w;
21 };
22 son a1[1000001];
23 int first[1000001],e;
24
25 void addbian(int u,int v,int w)
26 {
27     a1[e].v=v;
28     a1[e].w=w;
29     a1[e].u=u;
30     a1[e].next=first[u];
31     first[u]=e++;
32 }
34 int dui[10000001];
35 int he,en;
36 inline void clear(){he=1;en=0;}
37 inline void pop(){++he;}
38 inline bool empty(){return en>=he?0:1;}
39 inline int top(){return dui[he];}
40 inline void push(int x){dui[++en]=x;}
41
42 int n,m,S,T,dmax,sumdoor;
43 int ha[56][56][506];
44 int panduan;
45 char a[56][56];
46
47 struct son1
48 {
49     int x,y,val;
50 };
51 son1 ji[56][56][506];
52 int num[56][56];
53
54 queue<son1> q;
55
56 bool flag[56][56];
57 void Bfs(int x,int y)
58 {
59     while(!q.empty())q.pop();
60     mem(flag,0);
61     son1 now=(son1){x,y,0};
62     q.push(now);flag[x][y]=1;
63     while(!q.empty())
64     {
65         now=q.front();q.pop();
66         //printf("%d %d %d\n",now.x,now.y,now.val);
67         if(a[now.x][now.y]=='D'){ji[x][y][++num[x][y]]=now;continue;}
68         //flag在push进来之后就要标记，不然你懂得
69         if(now.x>1&&!flag[now.x-1][now.y]&&a[now.x-1][now.y]!='X'){q.push((son1){now.x-1,now.y,now.val+1});flag[now.x-1][now.y]=1;}
70         if(now.x<n&&!flag[now.x+1][now.y]&&a[now.x+1][now.y]!='X'){q.push((son1){now.x+1,now.y,now.val+1});flag[now.x+1][now.y]=1;}
71         if(now.y>1&&!flag[now.x][now.y-1]&&a[now.x][now.y-1]!='X'){q.push((son1){now.x,now.y-1,now.val+1});flag[now.x][now.y-1]=1;}
72         if(now.y<m&&!flag[now.x][now.y+1]&&a[now.x][now.y+1]!='X'){q.push((son1){now.x,now.y+1,now.val+1});flag[now.x][now.y+1]=1;}
73     }
74     if(!num[x][y])
75       panduan=1;
76 }
77
78 int dep[200006];
79 int bfs()
80 {
81     mem(dep,0);clear();
82     dep[S]=1;push(S);
83     while(!empty())
84     {
85         int now=top();pop();
86         //printf("now=%d\n",now);
87         for(int i=first[now];i!=-1;i=a1[i].next)
88         {
89             int temp=a1[i].v;
90             if(dep[temp]||!a1[i].w)continue;
91             dep[temp]=dep[now]+1;
92             push(temp);
93             if(temp==T)return 1;
94         }
95     }
96     return 0;
97 }
98
99 int dfs(int x,int val)
100 {
101     //printf("x=%d T=%d\n",x,T);
102     if(x==T)return val;
103     int val2=val,k;
104     for(int i=first[x];i!=-1;i=a1[i].next)
105     {
106         int temp=a1[i].v;
107         //printf("x=%d temp=%d\n",x,temp);
108         if(!a1[i].w||dep[temp]!=dep[x]+1||!val2)continue;
109         k=dfs(temp,minn(val2,a1[i].w));
110         if(!k){dep[temp]=0;continue;}
111         a1[i].w-=k;a1[i^1].w+=k;val2-=k;
112     }
113     return val-val2;
114 }
115
116 int Dinic()
117 {
118     int ans=0;
119     //cout<<1;
120     while(bfs())
121     {
122         //cout<<2;
123       ans+=dfs(S,INF);
124     }
125     return ans;
126 }
127
128 void chu()
129 {
130     mem(ha,0);
131     mem(a1,0);
132     mem(first,-1);
133     e=0;
134 }
135
136 int check(int time)
137 {
138     chu();
139
140     int now=0,ren;
141     for(int i=1;i<=n;++i)
142       for(int j=1;j<=m;++j)
143         if(a[i][j]=='.')
144             ha[i][j][0]=++now;
145     ren=now;
146     for(int i=1;i<=n;++i)
147       for(int j=1;j<=m;++j)
148         if(a[i][j]=='D')
149           for(int k=1;k<=time;++k)
150             ha[i][j][k]=++now;
151     S=0;T=now+1;
152     //printf("ren=%d\n",ren);
154     for(int i=1;i<=n;++i)
155       for(int j=1;j<=m;++j)
156         if(a[i][j]=='.')
157           for(int l=1;l<=num[i][j];++l)
158               for(int k=ji[i][j][l].val;k<=time;++k)
160
161     for(int i=1;i<=n;++i)
162       for(int j=1;j<=m;++j)
163         if(a[i][j]=='D')
164           for(int k=1;k<=time;++k)
166     //printf("now=%d\n",now);
167     //printf("e=%d\n",e);
168     return Dinic()==ren;
169 }
170
171 int er(int l,int r)
172 {
173     //printf("l=%d r=%d\n",l,r);
174     if(l==r)
175       return l;
176     int mid=(l+r)>>1;
177     if(check(mid))
178       return er(l,mid);
179     else
180       return er(mid+1,r);
181 }
182
183 int main(){
184     //freopen("1.txt","r",stdin);
185     //freopen("data6.in","r",stdin);
186     scanf("%d%d",&n,&m);
187     for(int i=1;i<=n;++i)
188       for(int j=1;j<=m;++j)
190     //cout<<0;
191     for(int i=1;i<=n;++i)
192       for(int j=1;j<=m;++j)
193             if(a[i][j]=='.')
194                 Bfs(i,j);
195     //printf("%d\n",ji[11][4].val);
196     //cout<<0;
197     //printf("dmax=%d\n",dmax);
198     //printf("ssss=%d %d\n",dmax,n*m+1);
199     if(panduan)puts("impossible");
200     else
201         printf("%d",er(1,n*m+1));
202     //while(1);
203     return 0;
204 }
code

posted @ 2017-07-30 21:47  A_LEAF  阅读(248)  评论(0编辑  收藏  举报