• Gym102361E Escape


    Link
    首先我们可以推出一些有用的结论:
    1、任意两个机器人之间的路线不能重合,但是可以垂直交叉。
    2、如果一个格子没有转向器,那么最多允许两个机器人以相互垂直的方向通过。
    3、如果一个格子有转向器,那么一定有且仅有一个机器人通过。
    考虑最大流模型。
    我们将图中的每个点拆成两个,一个水平点和一个竖直点。这两个点之间有一条容量为(1)的双向边。
    所有的水平点之间按水平的二连通相连,而所有的竖直点之间按竖直的而连通相连,流量均为(1)
    然后检查该图的最大流是否等于(a)即可。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int N=107,V=20007,E=130007,inf=1e9;
    int s,t,tot=1,head[V],ver[E],next[E],edge[E],dep[V],cur[V],id[N][N];char str[N];std::queue<int>q;
    int read(){int x;scanf("%d",&x);return x;}
    void add(int u,int v,int f)
    {
        ver[++tot]=v,next[tot]=head[u],edge[tot]=f,head[u]=tot;
        ver[++tot]=u,next[tot]=head[v],edge[tot]=0,head[v]=tot;
    }
    int bfs()
    {
        memset(dep+1,0x3f,t<<2),memcpy(cur+1,head+1,t<<2),dep[s]=0,q.push(s);
        for(int i,u,v;!q.empty();) for(u=q.front(),q.pop(),i=head[u];i;i=next[i]) if(dep[v=ver[i]]>inf&&edge[i]) dep[v]=dep[u]+1,q.push(v);
        return dep[t]<inf;
    }
    int dfs(int u,int lim)
    {
        if(!lim||u==t) return lim;
        int v,flow=0;
        for(int&i=cur[u],f;i;i=next[i])
            if(dep[v=ver[i]]==dep[u]+1&&(f=dfs(v,std::min(lim,edge[i]))))
            {
                flow+=f,lim-=f,edge[i]-=f,edge[i^1]+=f;
                if(!lim) break;
            }
        return flow;
    }
    int dinic()
    {
        int ans=0;
        while(bfs()) ans+=dfs(s,inf);
        return ans;
    }
    void solve()
    {
        memset(head+1,0,t<<2),memset(id,0,sizeof id),tot=1;
        int n=read(),m=read(),a=read(),b=read(),cnt=0;
        for(int i=1,j;i<=n;++i) for(scanf("%s",str+1),j=1;j<=m;++j) if(str[j]=='0') id[i][j]=++cnt;
        s=cnt*2+1,t=s+1;
        for(int i=1;i<=n;++i)
    	for(int j=1,u;j<=m;++j)
    	    if(u=id[i][j])
    	    {
    		add(u,u+cnt,1),add(u+cnt,u,1);
    		if(id[i-1][j]) add(u,id[i-1][j],1);
    		if(id[i+1][j]) add(u,id[i+1][j],1);
    		if(id[i][j-1]) add(u+cnt,id[i][j-1]+cnt,1);
    		if(id[i][j+1]) add(u+cnt,id[i][j+1]+cnt,1);
    	    }
        for(int i=1,x;i<=a;++i) if(id[1][x=read()]) add(s,id[1][x],1);
        for(int i=1,x;i<=b;++i) if(id[n][x=read()]) add(id[n][x],t,1);
        puts(dinic()==a? "Yes":"No");
    }
    int main(){for(int t=read();t;--t)solve();}
    
  • 相关阅读:
    java socket HTTPClient GET
    Spring的JdbcTemplate使用update或insert操作的三种使用例子
    windows XP 解决QQ和360软件冲突的办法
    J2EE 应用服务器集群常用方法
    javaeye被关闭了 被政 府和谐感
    P6SPY(JDBC SQL拦截)的安装和使用
    让QQ与360并存,不卸载360正常使用QQ
    Spring2.5注解(标注)学习笔记(使用annotation代替XML)
    centos vnc配置
    HTTP协议内容具体含义
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12376393.html
Copyright © 2020-2023  润新知