zoukankan      html  css  js  c++  java
  • codevs1022 覆盖[Hungary 二分图最大匹配]

    codevs1022 覆盖

    有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地。如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积。

    输入描述 Input Description

    输入文件的第一行是两个整数NM  (1<=NM<=100),第二行为一个整数K( K<=50),接下来的K行,每行两个整数X,Y表示K个水塘的行列位置。(1<=X<=N1<=Y<=M)。

    输出描述 Output Description

    输出所覆盖的最大面积块(1×2面积算一块)。

    样例输入 Sample Input

    4 4

    6

    1 1

    1 4

    2 2

    4 1

    4 2

    4 4

    样例输出 Sample Output

    4


    相邻的可以组成1*2建边,根据i+j奇偶分类就成了二分图,hungary求最大匹配(dinic当然也可以,本题规模没必要)

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=105;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,k,x,y,g[N][N];
    struct edge{
        int v,ne;
    }e[N*N*4];
    int h[N*N],cnt=0;
    inline int id(int i,int j){return (i-1)*n+j;}
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
    }
    void buildGraph(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) if(!g[i][j]&&(i+j)&1){
                if(i<n&&!g[i+1][j]) ins(id(i,j),id(i+1,j));
                if(j<m&&!g[i][j+1]) ins(id(i,j),id(i,j+1));
                if(i>1&&!g[i-1][j]) ins(id(i,j),id(i-1,j));
                if(j>1&&!g[i][j-1]) ins(id(i,j),id(i,j-1));
            }
    }
    int le[N*N],vis[N*N];
    bool find(int u){
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(vis[v]) continue;
            vis[v]=1;
            if(!le[v]||find(le[v])){
                le[v]=u;
                return true;
            }
        }
        return false;
    }
    int hungary(){
        int ans=0,nn=id(n,m);
        for(int i=1;i<=nn;i++){
            memset(vis,0,sizeof(vis));
            if(find(i)) ans++;
        }
        return ans;
    }
    int main(int argc, const char * argv[]) {
        n=read();m=read();k=read();
        while(k--){x=read();y=read();g[x][y]=1;}
        buildGraph();
        printf("%d",hungary());
        return 0;
    }
  • 相关阅读:
    codechef Graph on a Table
    CF1063F. String Journey
    BZOJ1547: 周末晚会
    maxsigma
    LOJ#2351. 「JOI 2018 Final」毒蛇越狱
    BZOJ3632: 外太空旅行
    图论:tarjan相关算法复习
    Codeforces 321E. Ciel and Gondolas(凸优化+决策单调性)
    5031. 【NOI2017模拟3.27】B (k次狄利克雷卷积)
    CSAcademy Round 10 Yury's Tree(有根树点分树或kruskal重构树)
  • 原文地址:https://www.cnblogs.com/candy99/p/6050779.html
Copyright © 2011-2022 走看看