zoukankan      html  css  js  c++  java
  • 377. 泥泞的区域(最大点集)

    377. 泥泞的区域

    二分图覆盖问题.

    首先需要用宽度为1,长度任意的模板将泥地覆盖.

    我们考虑每一个泥地,只有两个处理方式,要么是被一块横着的木板覆盖,要么是被一块竖着的木板覆盖.

    那么我们考虑将横着的木板与竖着的木板分开建图,对于每一个泥地将所属的横木与竖木连边.

    之后要求所有的泥地都要被覆盖,所以要选出最少的点将所有边覆盖.

    只就是最小点覆盖.==最大匹配

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=5010;
    int link[N],tot,n,m,id1[61][61],o,id2[61][61],vis[N],ans,match[N],p,hang;
    char c[61][61];
    struct edge{int y,next;}a[N*1000]; 
    vector<int>v1,v2;
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline void add(int x,int y)
    {
        a[++tot].y=y;
        a[tot].next=link[x];
        link[x]=tot;
    }
    inline bool dfs(int x)
    {
        for(int i=link[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if(vis[y]!=p)
            {
                vis[y]=p;
                if(!match[y]||dfs(match[y])) {match[y]=x;return true;}
            } 
        }
        return false;
    }
    int main()
    {
    //    freopen("1.in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=n;++i) scanf("%s",c[i]+1);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j) 
            {
                if(c[i][j]=='.') continue;
                int k=j;++o;
                while(k<=m&&c[i][k]=='*') id1[i][k]=o,++k;
                j=k;  
            }    
        hang=o;    
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j) 
            {
                if(c[j][i]=='.') continue;
                int k=j;++o;
                while(k<=n&&c[k][i]=='*') id2[k][i]=o,++k;
                j=k;
            }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j) if(c[i][j]=='*') add(id1[i][j],id2[i][j]);
        for(int i=1;i<=hang;++i) 
        {
            ++p;
            if(dfs(i)) ans++;
        }        
        printf("%d",ans);
        return 0;
    }
    View Code

    我敢保证这绝对是我打的最ugly的代码了(没有之一)

    同时也祝自己AcWing上一百道题了!!!

  • 相关阅读:
    正态分布与中心极限定理
    超几何分布与二项分布及其期望
    cf492E. Vanya and Field(扩展欧几里得)
    ZR#317.【18 提高 2】A(计算几何 二分)
    小米OJ刷题日志
    cf519D. A and B and Interesting Substrings(前缀和)
    cf519C. A and B and Team Training(找规律)
    BZOJ2118: 墨墨的等式(最短路 数论)
    Service生命周期图
    python2.7中使用mysql (windows XP)
  • 原文地址:https://www.cnblogs.com/gcfer/p/12469530.html
Copyright © 2011-2022 走看看