zoukankan      html  css  js  c++  java
  • HDU 4185

    题意

    给出一个 n * n的油田,现在要撇去一些油,但是每次只能撇掉1 * 2或者2 *1的油,问最多能撇多少次。

    思路

    匹配
    建图:给每个“#”标序号后,dfs找每个油田位置的上下左右是否有油田,若有则建边。跑匈牙利匹配即可。

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int maxn = 600+5;
    int turn[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    char s[maxn][maxn];
    int num[maxn][maxn];
    int g[maxn][maxn];
    int match[maxn];
    bool used[maxn];
    int n, k;
    int number;
    
    bool dfs(int v)
    {
        for(int j = 1; j <= number; j++){
            if(g[v][j] && !used[j]){
                used[j] = 1;
                if(match[j] == 0 || dfs(match[j]) == 1){
                    match[j] = v;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hungary()
    {
        int res = 0;
        memset(match, 0, sizeof match);
        for(int v = 1; v <= number; v++){
            memset(used, 0, sizeof used);
            if(dfs(v)) res++;
        }
        return res;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int kase = 1; kase <= T; kase++){
            scanf("%d",&n);
            memset(num, 0, sizeof num);
            memset(g, 0, sizeof g);
            number = 0;
            for(int i = 0; i < n; i++){
                scanf("%s",&s[i]);
                for(int j = 0; j < n; j++){
                    if( s[i][j] == '#' ){
                        num[i][j] = ++number;
                    }
                }
            }
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    if( s[i][j] == '#' ){
                        for(int k = 0; k < 4; k++){
                            int x = i + turn[k][0], y = j + turn[k][1];
                            if( x >= 0 && x < n && y >= 0 && y < n && s[x][y] == '#' ){
                                int n1 = num[i][j], n2 = num[x][y];
                                g[n1][n2] = 1;
                            }
                        }
                    }
                }
            }
            int ans = hungary();
            printf("Case %d: %d
    ",kase,ans/2);
        }
        return 0;
    }
    
  • 相关阅读:
    win10 uwp 如何判断一个对象被移除
    win10 uwp 如何判断一个对象被移除
    上传代码 CodePlex
    上传代码 CodePlex
    如何使用 Q#
    让 AE 输出 MPEG
    让 AE 输出 MPEG
    解决 vs 出现Error MC3000 给定编码中的字符无效
    解决 vs 出现Error MC3000 给定编码中的字符无效
    PHP date_date_set() 函数
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740518.html
Copyright © 2011-2022 走看看