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;
    }
  • 相关阅读:
    maven surefire入门
    编译原理随笔4(自下而上的语法分析-递归法)
    编译原理随笔3(自上而下的语法分析-推导法)
    编译原理随笔1
    LeetCode刷题笔记-DP算法-取数问题
    算法刷题笔记-stack-四则运算
    LeetCode刷题笔记-递归-反转二叉树
    Beta里程碑总结
    评价cnblogs.com的用户体验
    我们的团队目标
  • 原文地址:https://www.cnblogs.com/yigexigua/p/3889521.html
Copyright © 2011-2022 走看看