• Fire Net HDU


    题意:

    给出一张图,图中'X'表示wall,'.'表示空地,可以放置blockhouse同一条直线上只能有一个blockhouse,除非有wall

    隔开,问在给出的图中最多能放置多少个blockhous

    分析:

    把原始图分别按行和列缩点  
    建图:横竖分区。先看每一列,同一列相连的空地同时看成一个点,显然这样的区域不能够同时放两个点。这些

    点作为二分图的X部。同理在对所有的行用相同的方法缩点,作为Y部。  
      连边的条件是两个区域有相交部分(即'.'的地方)。最后求最大匹配就是答案。

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    struct node
    {
        int a = 0 , b = 0;
    };
    node id[6][6];
    char mp[6][6];
    bool link[105][105];
    bool vis[105];
    int use[105];
    int hcnt,rcnt;
    
    void dfsh(int x,int y){
        if(y <= n && mp[x][y] == '.'){
            id[x][y].a = hcnt;
            dfsh(x,y+1);
        }
    }
    
    void dfsr(int x,int y){
        if(x <= n && mp[x][y] == '.'){
            id[x][y].b = rcnt;
            dfsr(x+1,y);
        }
    }
    
    int find(int x)
    {
        for (int s = 1; s < rcnt; s++) {
            if (link[x][s] && !vis[s]) {
                vis[s] = 1;
                if (use[s] == 0 || find(use[s])) {
                    use[s] = x;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main(int argc, char const *argv[])
    {
        while(cin >> n && n){
            for(int i = 1;i <= n ;i ++){
                cin >> mp[i] + 1;
            }
    
                memset(id,0,sizeof id);
                memset(link,0,sizeof link);
                memset(use,0,sizeof use);
                hcnt = rcnt = 1;
                for(int i = 1;i <= n;i ++){
                    for(int j = 1;j <= n ;j ++){
                        if(mp[i][j] == 'X'){
                            continue;
                        }
                        if(id[i][j].a == 0){
                            dfsh(i,j);
                            hcnt ++;
                        }
                        if(id[i][j].b == 0){
                            dfsr(i,j);
                            rcnt ++;
                        }
                        link[id[i][j].a][id[i][j].b] = 1;
                    }
                }
                int sum = 0;
                for(int i = 1;i < hcnt;i ++){
                    memset(vis,0,sizeof vis);
                    if(find(i)) sum ++;
                }
                printf("%d
    ",sum );
            }
    
        
        return 0;
    }
  • 相关阅读:
    kubeadm升级证书-集群已GG
    匿名内部类
    JAVA中Integer的==和equals注意
    编写高效优雅安全Java程序的常见原则
    图解排序算法(二)之希尔排序
    String常见问题
    ActiveMQ 2
    消息中间件概述和AaciveMQ 1
    类加载器-5
    使用MyBatis编写Dao的两种语法
  • 原文地址:https://www.cnblogs.com/DWVictor/p/11343288.html
Copyright © 2020-2023  润新知