zoukankan      html  css  js  c++  java
  • zoj1654二分图

      题意:输入一个地图,*是草坪 # 是墙 o是空地。机器人只能放在空地上,且两个同行或者同列的机器人中间必须有墙,问最多可以放多少个机器人。

    书上给出:......将行视为x    , 列视为 y. 求 x 与 y 这个2分图之间的最大匹配。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    #include<math.h>
    using namespace std;
    int numx;int numy;
    const int maxn=51;
    int link[maxn*maxn];
    int xx[maxn*maxn],yy[maxn*maxn];
    int x[maxn][maxn];
    int y[maxn][maxn];
    int used[maxn*maxn];
    int g[maxn*maxn][maxn*maxn];
    int dfs(int x)
    {
        for(int i=1;i<=numy;i++){
            if(g[x][i]&&!used[i]){
                used[i]=1;
                if(link[i]==-1||dfs(link[i])){
                    link[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    void solve()
    {
        int ans=0;
        for(int i=1;i<=numx;i++){
            memset(used,0,sizeof(used));
            if(dfs(i)) ans++;
        }
        cout<<ans<<endl;
    }
    int main()
    {
        char str[maxn][maxn];
        int Icase;
        int n,m;
        scanf("%d",&Icase);
        int k=0;
        while(Icase--){
            memset(link,-1,sizeof(link));
            k++;
            memset(x,0,sizeof(x));
            memset(y,0,sizeof(y));
            memset(g,0,sizeof(g));
            scanf("%d%d",&m,&n);
            for(int i=0;i<m;i++)
                scanf("%s",str[i]);
            numx=0;numy=0;
            for(int i=0;i<m;i++){
                int flag=0;
                for(int j=0;j<n;j++){
                    if(str[i][j]=='o'){
                        if(!flag) numx++;
                        x[i][j]=numx;flag=1;
                    }
                    else if(str[i][j]=='#') flag=0;
                }
            }
            for(int j=0;j<n;j++){
                int flag=0;
                for(int i=0;i<m;i++){
                    if(str[i][j]=='o'){
                        if(!flag) numy++;
                        y[i][j]=numy;flag=1;
                    }
                    else if(str[i][j]=='#') flag=0;
                }
            }
            for(int i=0;i<m;i++)
                for(int j=0;j<n;j++)
                if(x[i][j]) g[x[i][j]][y[i][j]]=1;
            printf("Case :%d
    ",k);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    超贴心的,手把手教你写爬虫
    人生苦短我用Python,本文助你快速入门
    RocketMQ 安装
    RocketMQ 简介
    2020年工作上的最大收获——监控告警体系
    .NET Core开源任务调度平台ScheduleMaster上新了
    从源码角度分析ScheduleMaster的节点管理流程
    使用 K8s 进行作业调度实战分享
    图解 K8s 核心概念和术语
    深度剖析 Kafka Producer 的缓冲池机制【图解 + 源码分析】
  • 原文地址:https://www.cnblogs.com/yigexigua/p/3889521.html
Copyright © 2011-2022 走看看