AcWing372。チェッカーボードカバレッジ

アルゴリズム

二部グラフ+マッチング

アイデア

エッジ

ドミノは2つのグリッドをリンクし、グリッドはノードであり、ドミノは2つのグリッドを接続するエッジです。

0要素

同じ色のグリッドの間にエッジがないように、グリッドを白黒で染色します。

1要素

各グリッドは1つのドミノでのみカバーでき、エッジは1つだけです。

知識

ハンガリー

bool dfs(int x){ 
    for(unsigned int i = 0; i <e [x] .size(); i ++){ 
        int y = e [x] [i]; 
        (v [y])が継続する場合。
        v [y] = 1; 
        if(f [y] == -1 || dfs(f [y])){ 
            f [y] = x; 
            1を返します。
        } 
    } 
    0を返します。
}

  

二部グラフマッチング

Zeng Guangluプラス1があります。

コード

#include <cstdio> 
#include <vector> 
#include <cstring> 
#include <iostream> 
using namespace std; 
const int N = 106; 
const int dx [4] = {0,0,1、-1}; 
const int dy [4] = {1、-1,0,0}; 
int n、m、ans、f [N * N]; 
bool b [N] [N]、v [N * N]; 
vector <int> e [N * N]; 

bool dfs(int x){ 
    for(unsigned int i = 0; i <e [x] .size(); i ++){ 
        int y = e [x] [i]; 
        (v [y])が継続する場合。
        v [y] = 1; 
        if(f [y] == -1 || dfs(f [y])){ 
            f [y] = x; 
            1を返します。
        } 
    } 
    0を返します。
} 

int main(){ 
    cin >> n >> m;
    while(m--){ 
        int x、y; 
        scanf( "%d%d"、&x、&y); 
        b [x-1] [y-1] = 1; 
    } 
    for(int i = 0; i <n; i ++)
        for(int j = 0; j <n; j ++)
            if(!b [i] [j])
                for(int k = 0; k <4; k ++ ){ 
                    int x = i + dx [k]、y = j + dy [k]; 
                    if(x> = 0 && x <n && y> = 0 && y <n &&!b [x] [y]){ 
                        e [i * n + j] .push_back(x * n + y); 
                        e [x * n + y] .push_back(i * n + j); 
                    } 
                } 
    memset(f、-1、sizeof(f)); 
    for(int i = 0; i <n;
            if((i ^ j)&1)continue; 
            memset(v、0、sizeof(v)); 
            ans + = dfs(i * n + j); 
        } 
    cout << ans << endl; 
    return 0; 
} 

Author :Ruanmowen 
リンク:https 
://www.acwing.com/activity/content/code/content/274974/出典:AcWingの
著作権は著者に帰属します。営利目的の複製については、作者に連絡して承認を得てください。非営利目的の複製については、出典を明記してください。

  

 

おすすめ

転載: www.cnblogs.com/ruanmowen/p/12724213.html