ZOJ 1002 Fire Net (搜索 || 二分图)

来源:互联网 发布:python数据分析的书 编辑:程序博客网 时间:2024/05/09 08:07

可以把一行分成多行,一列分出多列,然后用行和列坐标之间建二分图,求最大匹配.

#include <iostream>#include <cstdio>#include <memory.h>using namespace std;const int maxn = 40;char grid[5][5];bool g[maxn][maxn], vis[maxn];int rg[5][5], cg[5][5], fa[maxn], n, m;bool dfs(int u){for (int v = 1; v <= m; ++v){if(g[u][v] && !vis[v]){vis[v] = 1;if(fa[v] == 0 || dfs(fa[v])){fa[v] = u;return true;}}}return false;}int hungary(){int ans = 0;memset(fa, 0, sizeof(fa));for (int i = 1; i <= n; ++i){memset(vis, 0, sizeof(vis));if(dfs(i))ans++;}return ans;}int main(){while (scanf("%d\n", &n) && n){memset(g, 0, sizeof(g));memset(rg, 0, sizeof(rg));memset(cg, 0, sizeof(cg));for (int i = 0; i < n; ++i){gets(grid[i]);}int r = 1;for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){if(grid[i][j] == 'X'){r++;}else{rg[i][j] = r;}}++r;}int c = r + 1;for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){if(grid[j][i] == 'X'){c++;}else{cg[j][i] = c;}}++c;}for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){if(grid[i][j] == '.'){g[rg[i][j]][cg[i][j]] = g[cg[i][j]][rg[i][j]] = 1;}}}n = r, m = c;printf("%d\n",hungary());}return 0;}

搜索的做法:

#include <iostream>#include <cstdio>#include <memory.h>using namespace std;const int maxn = 5;char grid[maxn][maxn];bool vis[maxn][maxn];int  di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1}, n, ans;bool canput(int ci, int cj){for (int i = 0; i < 4; ++i){for (int ti = ci, tj =cj; ti >= 0 && ti < n && tj >= 0 && tj < n && grid[ti][tj] == '.'; ti += di[i], tj += dj[i]){if(vis[ti][tj])return false;}}return true;}void dfs(int cp, int cnt){if(cnt > ans){ans = cnt;}if(cp >= n * n)return;int ci = cp / n, cj = cp %n;if(grid[ci][cj] == '.' && canput(ci, cj)){vis[ci][cj] = 1;dfs(cp + 1, cnt + 1);vis[ci][cj] = 0;}dfs(cp + 1, cnt);}int main(){while (scanf("%d\n", &n) && n){for (int i = 0; i < n; ++i){gets(grid[i]);}ans = 0;memset(vis, 0, sizeof(vis));dfs(0, 0);printf("%d\n", ans);}return 0;}


原创粉丝点击