zoukankan      html  css  js  c++  java
  • 372. 棋盘覆盖(最大匹配)

    372. 棋盘覆盖

    挺好的一题,提出了二分图一般的解题思路...

    由于二分图分为左右两个不同的点集,所以保证1和0的性质.

    1:即左边的点最多与右边的一个点相连.

    0:即同侧的点不可能相连.

    我们观察这道题。如果将棋盘染色,行列相加为奇数为黑色,偶数为白色.这样就可以讲点分成两类.

    显然同色的点不可能被1*2的方格覆盖,同时每个点只能被一个1*2覆盖符合性质..

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=110,M=10010,INF=1e9;
    int n,m,s,t,link[M],tot=1,dx[4]={-1,1,0,0},dy[4]={0,0,1,-1},d[M];
    bool vis[N][N];
    struct edge{int y,v,next;}a[M<<4];
    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,int v)
    {
        a[++tot].y=y;a[tot].v=v;a[tot].next=link[x];link[x]=tot;
        a[++tot].y=x;a[tot].v=0;a[tot].next=link[y];link[y]=tot;
    }
    inline bool bfs()
    {
        queue<int>q;q.push(s);
        memset(d,0,sizeof(d));
        d[s]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=link[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(a[i].v&&!d[y])
                {
                    d[y]=d[x]+1;
                    q.push(y);
                    if(y==t) return true;
                }
            }
        }
        return false;
    }
    inline int dinic(int x,int flow)
    {
        if(x==t) return flow;
        int rest=flow,k;
        for(int i=link[x];i&&rest;i=a[i].next)
        {
            int y=a[i].y;
            if(a[i].v&&d[y]==d[x]+1)
            {
                k=dinic(y,min(rest,a[i].v));
                if(!k) d[y]=0;
                a[i].v-=k;
                a[i^1].v+=k;
                rest-=k;
            }
        }
        return flow-rest;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=m;++i)
        {
            int x=read(),y=read();
            vis[x][y]=1;
        }
        s=0;t=n*n+1;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                if(!vis[i][j])
                {
                    if((i+j)%2==0)
                    {    
                        add(s,(i-1)*n+j,1);
                        for(int k=0;k<4;++k)
                        {
                            int x=i+dx[k];
                            int y=j+dy[k];
                            if(x>=1&&x<=n&&y>=1&&y<=n&&!vis[x][y]) add((i-1)*n+j,(x-1)*n+y,1);
                        }
                    }        
                    else add((i-1)*n+j,t,1);
                }
            }
        int maxflow=0,flow;
        while(bfs())
            while(flow=dinic(s,INF)) maxflow+=flow;
        printf("%d",maxflow);
        return 0;
    }
    View Code
  • 相关阅读:
    Django框架 之 querySet详解
    Django框架 之 admin管理工具(组件使用)
    Django框架 之 跨域请求伪造
    Django框架 之 form组件的钩子
    Django框架 之 Form表单和Ajax上传文件
    Django框架 之 modelform组件
    [BZOJ4477] [JSOI2015]字符串树(可持久化Trie+LCA)
    [BZOJ 4523] [CQOI2016]路由表(Trie+单调栈)
    [Luogu2870] [USACO07DEC]最佳牛线Best Cow Line(贪心+后缀数组)
    [BZOJ3998][TJOI2015]弦论(后缀数组)
  • 原文地址:https://www.cnblogs.com/gcfer/p/12444617.html
Copyright © 2011-2022 走看看