【题解】gym102361E Escape(分层图)

【题解】gym102361E Escape(分层图)

https://vjudge.net/problem/Gym-102361E

容易证明不会存在共用转换器的合法方案,因为出口互不相同且一旦共用转换器,要么以后走一样的路(这样就到最后两个机器人到了一个出口),要么有一个机器人的路径是非法的(同理)。

由此可以推断一段路径最多只会被一个机器人覆盖(路径相交不算)

这道题最主要是观察到这个性质。然后就可以做了。

建立两张网格图G1和G2,一张图只有上下的边,另一张图只有左右的边。两张图的对应格子连一条双向边。出入口在G1上处理一下即可。

//@winlere
#include
#include
#include
#include
#include

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 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;
}

你可能感兴趣的:(【题解】gym102361E Escape(分层图))