zoukankan      html  css  js  c++  java
  • [ TJOI 2010 ] 打扫房间

    (\)

    Description


    给出一个(N imes M) 的网格,一些格子是污点,求是否能用多个封闭的环路覆盖所有不是污点的格点。

    封闭的环路覆盖的含义是,每条路径都必须是一个环,且每一个格点正好只被一条路径覆盖。图是四联通的。

    • (N,Mle 30)

    (\)

    Solution


    一开始以为是插头,后来发现只能做(50\%)的数据......

    将图黑白染色。注意到一个合法的图一定满足每个格点正好进出各一次。每个黑点只能由周围至多的四个白点进出,白点同理。

    所以理论上应该是每个格点都正好达到,向一个异色格点流一股流,从一个异色个点流入一股流,且两个异色格点不为同一个点。

    将问题转化一下,把白色格点流向黑色格点的流反向。

    这样每个黑色格点正好流出两股流,每个白色格点正好流入两股流,我们再加上源汇,源向黑色点流量为 (2) ,白色点向汇流量为 (2)

    这样就转化为满流的判定问题了。

    (\)

    Code


    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 910
    #define R register
    #define gc getchar
    #define inf 2000000000
    using namespace std;
    
    inline int rd(){
      int x=0; bool f=0; char c=gc();
      while(!isdigit(c)){if(c=='-')f=1;c=gc();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
      return f?-x:x;
    }
    
    bool mp[N][N];
    int n,m,s,t,g,tot,cnt,sum,hd[N],h[N],dp[N],num[35][35];
    
    struct edge{int to,nxt,w;}e[N*100];
    
    inline void add(int u,int v,int w){
      e[++tot].to=v; e[tot].w=w;
      e[tot].nxt=hd[u]; hd[u]=tot;
    }
    
    queue<int> q;
    
    inline bool bfs(){
      memset(dp,0,sizeof(dp));
      dp[s]=1; q.push(s);
      while(!q.empty()){
        int u=q.front(); q.pop();
        for(R int i=hd[u],v;i;i=e[i].nxt)
          if(e[i].w&&!dp[v=e[i].to]){
            dp[v]=dp[u]+1; q.push(v);
          }
      }
      return dp[t];
    }
    
    int dfs(int u,int flow){
      if(u==t||!flow) return flow;
      R int res=0,tmp;
      for(R int &i=h[u],v;i;i=e[i].nxt)
        if(e[i].w&&(dp[v=e[i].to]==dp[u]+1)){
          tmp=dfs(v,min(e[i].w,flow-res));
          e[i].w-=tmp; e[i^1].w+=tmp; res+=tmp;
          if(res==flow) return flow;
        }
      return res;
    }
    
    inline int dinic(){
      int res=0;
      while(bfs()){
        memcpy(h,hd,sizeof(hd));
        res+=dfs(s,inf);
      }
      return res;
    }
    
    
    inline void work(){
      n=rd(); m=rd();
      cnt=g=s=sum=0;
      t=n*m+1; tot=1;
      memset(hd,0,sizeof(hd));
      char c;
      for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j){
          c=gc(); while(c!='.'&&c!='#') c=gc();
          mp[i][j]=(c!='#');
          num[i][j]=++cnt;
          if(c!='#') ++g;
          if((i+j)&1){
            if(mp[i][j]){add(s,cnt,2);add(cnt,s,0);sum+=2;}
          }
          else if(mp[i][j]){add(cnt,t,2);add(t,cnt,0);}
        }
      if(g&1){puts("NO");return;}
      for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
        if(mp[i][j]&&((i+j)&1)){
          if(i!=1&&mp[i-1][j]){add(num[i][j],num[i-1][j],1);add(num[i-1][j],num[i][j],0);}
          if(i!=n&&mp[i+1][j]){add(num[i][j],num[i+1][j],1);add(num[i+1][j],num[i][j],0);}
          if(j!=1&&mp[i][j-1]){add(num[i][j],num[i][j-1],1);add(num[i][j-1],num[i][j],0);}
          if(j!=m&&mp[i][j+1]){add(num[i][j],num[i][j+1],1);add(num[i][j+1],num[i][j],0);}
        }
        int ans=dinic();
        puts((ans==sum)?"YES":"NO");
    }
    
    int main(){
      int t=rd();
      while(t--) work();
      return 0;
    }
    
    
  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9770405.html
Copyright © 2011-2022 走看看