• POJ 2226 二分图最小覆盖


    题意:
    这里写图片描述
    这里写图片描述

    思路:
    把横着的连通块放在一个集合 竖着的放在一个集合

    如果有交 就连边
    求最小覆盖即可 (数值上等于最大匹配)

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 2555*2555
    int n,m,first[2555],next[N],v[N],tot,cnt,change[55][55],changea[55][55],vis[2555],matched[2555],ans;
    char a[55][55];
    void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    bool dfs(int x){
        for(int i=first[x];~i;i=next[i]){
            if(!vis[v[i]]){
                vis[v[i]]=1;
                if(!matched[v[i]]||dfs(matched[v[i]])){
                    matched[v[i]]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main(){
        memset(first,-1,sizeof(first));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            getchar();
            for(int j=1;j<=m;j++)
                a[i][j]=getchar();
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(a[i][j]=='*'){
                    if(a[i][j-1]=='*')
                        changea[i][j]=changea[i][j-1];
                    else changea[i][j]=++cnt;
                }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(a[i][j]=='*'){
                    if(a[i-1][j]=='*')
                        change[i][j]=change[i-1][j];
                    else change[i][j]=++cnt;
                    add(changea[i][j],change[i][j]);
                }
        for(int i=1;i<=cnt;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
        }
        printf("%d
    ",ans);
    }

    这里写图片描述

  • 相关阅读:
    SQL注入实验-2021.01.24
    数据库的搭建与基本语句2021-01-24
    Linux
    磁盘配置
    在Vmware中Centos下的Hadoop环境搭建
    Linux系统(CentOS)-2021.1.19
    中间件,JavaScript,PHP及burpSuite暴力破解实验-2021.1.16
    html,css学习笔记-2021.1.15
    第一周学习视频(二)
    第一周学习视频(一)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532207.html
Copyright © 2020-2023  润新知