【题解】gym102361E Escape(分层图)
【题解】gym102361E Escape(分层图)
https://vjudge.net/problem/Gym-102361E
容易证明不会存在共用转换器的合法方案,因为出口互不相同且一旦共用转换器,要么以后走一样的路(这样就到最后两个机器人到了一个出口),要么有一个机器人的路径是非法的(同理)。
由此可以推断一段路径最多只会被一个机器人覆盖(路径相交不算)
这道题最主要是观察到这个性质。然后就可以做了。
建立两张网格图G1和G2,一张图只有上下的边,另一张图只有左右的边。两张图的对应格子连一条双向边。出入口在G1上处理一下即可。
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; typedef long long ll;
inline int qr(){
int ret=0,f=0,c=getchar();
while(!isdigit(c)) f|=c==45,c=getchar();
while( isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=2e4+5;
int head[maxn],cur[maxn],d[maxn],cnt,S,T,id[105][105],n,m,a,b,pa[105],pb[105];
char c[105][105];
struct E{int to,nx,w;}e[maxn<<4];
void add(int fr,int to,int w,int init=0){
static int cnt=1;
if(init) return cnt=1,void();
e[++cnt]=(E){to,head[fr],w}; head[fr]=cnt;
e[++cnt]=(E){fr,head[to],0}; head[to]=cnt;
}
bool bfs(){
memset(d,0,sizeof d);
memcpy(cur,head,sizeof cur);
static queue<int> q;
d[S]=1; q.push(S);
while(q.size()){
int now=q.front();
q.pop();
for(int t=head[now];t;t=e[t].nx)
if(e[t].w>0&&!d[e[t].to])
q.push(e[t].to),d[e[t].to]=d[now]+1;
}
return d[T];
}
int dfs(int now,int fl){
if(now==T||fl==0) return fl;
int ret=0,p;
for(int&t=cur[now];t;t=e[t].nx)
if(d[e[t].to]==d[now]+1)
p=dfs(e[t].to,min(e[t].w,fl)),fl-=p,ret+=p,e[t].w-=p,e[t^1].w+=p;
return ret;
}
int Dinic(){
int ret=0;
while(bfs()) ret+=dfs(S,1e9);
return ret;
}
int calch(int i,int j){return 3+((i-1)*m+j-1)*2;}
int calcv(int i,int j){return 4+((i-1)*m+j-1)*2;}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
int TT=qr();
while(TT--){
n=qr(); m=qr(); a=qr(); b=qr();
memset(head,0,sizeof head); add(1,1,1,1);
for(int t=1;t<=n;++t) scanf("%s",c[t]+1);
S=1; T=2;
for(int t=1;t<=a;++t) pa[t]=qr();
for(int t=1;t<=b;++t) pb[t]=qr();
for(int t=1;t<=n-1;t++)
for(int i=1;i<=m;i++)
if(c[t][i]=='0' && c[t+1][i]=='0')
add(calcv(t,i),calcv(t+1,i),1),
add(calcv(t+1,i),calcv(t,i),1);
for(int t=1;t<=n;t++)
for(int i=1;i<=m-1;i++)
if(c[t][i]=='0'&&c[t][i+1]=='0')
add(calch(t,i),calch(t,i+1),1),
add(calch(t,i+1),calch(t,i),1);
for(int t=1;t<=n;t++)
for(int i=1;i<=m;i++)
if(c[t][i]=='0')
add(calch(t,i),calcv(t,i),1),
add(calcv(t,i),calch(t,i),1);
for(int t=1;t<=a;t++) if(c[1][pa[t]]=='0') add(1,calcv(1,pa[t]),1);
for(int t=1;t<=b;t++) if(c[n][pb[t]]=='0') add(calcv(n,pb[t]),2,1);
int sav=Dinic();
if(sav==a) puts("Yes");
else puts("No");
}
return 0;
}
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!