2部グラフのマッチング
コンテンツ
2008年のGoogle Code Jamをちょっとだけやった.
2部グラフのマッチングの応用があった.
模範回答(?)のコードが想像以上に短かった.
こんな感じ.
#include <iostream> #include <vector> #include <cstring> using namespace std; #define FILL(xs, x) memset(xs, x, sizeof((xs))) const int M = 100, N = 100; int m, n, ind, matchX[M][N], matchY[M][N], visited[M][N], count; bool room[M][N]; bool dfs(int x, int y) { if (x < ) return true; if (visited[x][y] == count) return false; visited[x][y] = count; for (int i = x-1; i <= x+1; i++) for (int j = y-1; j <= y+1; j+=2) if ( <= i && i < m && <= j && j < n && room[i][j]) if ( dfs(matchX[i][j], matchY[i][j]) ) { matchX[i][j] = x; matchY[i][j] = y; matchX[x][y] = i; matchY[x][y] = j; return true; } return false; } int solve() { int ret = ; count = ; FILL(matchX,-1); FILL(matchY,-1); FILL(visited,); for (int i = ; i < m; i++) for (int j = ; j < n; j++) if (room[i][j]) { ret++; if (j%2==1) { count++; if (dfs(i,j)) ret--; } } return ret; } int main() { int testCase; cin >> testCase; for (int iCase = 1; iCase <= testCase; iCase++) { cin >> m >> n; for (int i = ; i < m; i++) for (int j = ; j < n; j++) { char c; cin >> c; room[i][j] = c == '.'; } cout << "Case #" << iCase << ": " << solve() << endl; } return ; }
無駄が無いコードになっている.再帰をつかって簡潔になっている.
2部グラフのマッチングはこういうふうに書ける,というのは常識なんでしょうか?
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)