Gym 101201.G - Maximum Islands(最小顶点覆盖)
2017-10-24 12:31
465 查看
题意:给你一个50*50 的图,里面有LWC三种字符,L代表陆地,W代表水,C代表可以由你决定是水还是陆地,问你这个图中L的联通块最多有几块。
思路:首先很容易想到把所有L联通块周围围上W,剩下的就是C了,然后我们可以发现要使得L的联通块最多,那么就尽量每个联通块只占用给一个点,那么就变成了剩下的C连成的图,划分成两个点集,然后成为一个最小顶点覆盖问题,由于是二分图,所有转换成二分最大匹配,无向图的二分匹配随便搞搞。
思路:首先很容易想到把所有L联通块周围围上W,剩下的就是C了,然后我们可以发现要使得L的联通块最多,那么就尽量每个联通块只占用给一个点,那么就变成了剩下的C连成的图,划分成两个点集,然后成为一个最小顶点覆盖问题,由于是二分图,所有转换成二分最大匹配,无向图的二分匹配随便搞搞。
#include <bits/stdc++.h> using namespace std; const int maxn = 100 + 5; vector<int>G[2500 + 5]; int used[2500 + 5], match[2500 + 5]; bool dfs(int v) { used[v] = 1; for(int i = 0; i < G[v].size(); i++) { int u = G[v][i], w = match[u]; if(w < 0 || !used[w] && dfs(w)) { match[v] = u; match[u] = v; return true; } } return false; } int hungary(int V) { int res = 0; memset(match, -1, sizeof(match)); for(int u = 1; u <= V; u++) { if(match[u] < 0) { memset(used, 0, sizeof(used)); if(dfs(u)) res++; } } return res; } int n, m; int dx[] = {0, 0, 4000 -1, 1}; int dy[] = {1, -1, 0, 0}; int vis[maxn][maxn]; char ma[maxn][maxn]; void dfs(int x, int y) { vis[x][y] = 1; for(int i = 0; i < 4; i++) { int fx = dx[i] + x; int fy = dy[i] + y; if(0 <= fx && fx < n && 0 <= fy && fy < m) { if(ma[fx][fy] == 'C') ma[fx][fy] = 'W'; else if(ma[fx][fy] == 'L' && vis[fx][fy] == 0) dfs(fx, fy); } } } int main() { cin >> n >> m; for(int i = 0; i < n; i++) cin >> ma[i]; int ans = 0; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(ma[i][j] == 'L' && vis[i][j] == 0) { dfs(i, j), ans++; } } } int id = 1; map<pair<int,int>, int>rec; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(ma[i][j] == 'C') { if(rec[{i,j}] == 0) rec[{i,j}] = id++; for(int k = 0; k < 4; k++) { int fx = i + dx[k], fy = j + dy[k]; if(0 <= fx && fx < n && 0 <= fy && fy < m) { if(ma[fx][fy] == 'C') { if(rec[{fx,fy}] == 0) rec[{fx, fy}] = id++; int idx1 = rec[{i,j}], idx2 = rec[{fx, fy}]; G[idx1].push_back(idx2); G[idx2].push_back(idx1); } } } } } } int vs = id - 1; if(vs) ans = ans + vs - hungary(vs); cout << ans << endl; return 0; }
相关文章推荐
- 【二分匹配入门专题1】G - Asteroids poj3041【最小顶点覆盖】
- POJ3041 最小顶点覆盖
- Asteroids POJ3041 二分图最小顶点覆盖
- hdu 1150 Machine Schedule 最小顶点覆盖(最大匹配)
- hdu 3360 National Treasures 最小顶点覆盖(最大匹配)
- poj 3041 二分图最小顶点覆盖 小行星删行或列
- poj 2226 Muddy Fields 最小顶点覆盖
- poj1325 最小顶点覆盖 konig定理
- HDOJ---1151 Air Raid[匈牙利算法:最小路径覆盖数=原图顶点数–二分图最大匹配数]
- 关于二分图中对最小顶点覆盖、最小边覆盖、最大独立集的总结
- HDU1054+最小顶点覆盖
- 【bzoj 1735】Muddy Fields 泥泞的牧场(最小割/最小顶点覆盖)
- POJ3692——Kindergarten (二分图求最小顶点覆盖 (即最大匹配))
- UVA 1292 - Strategic game(最小顶点覆盖问题,覆盖所有边,自己版本待解)
- HDU1150 Machine Schedule(最小顶点覆盖)
- LA 2038 Strategic game(二分图最小顶点覆盖 /树形DP)
- poj3041 - Asteroids (二分图最小顶点覆盖)
- hdu2119Matrix (二分匹配,最小顶点覆盖)
- poj1325最小顶点覆盖
- 二分图的最小顶点覆盖 和 最大独立集 和 最大团