HDU
来源:互联网 发布:淘宝 小电影 编辑:程序博客网 时间:2024/06/07 09:49
题意:有一个农场大小为n*m 里面有一些古老的农田,你现在需要新建一些农田,要求新建的农田之间不能相连,古老的农田不可拆分,如果你选择了一块土地(原为古老的农田)建立新农田则该新农田需要把一整块连通的古老的农田全部包含。问最多能新建多少个农田。
思路:由于古老的农田只有10个,因此我们可以枚举选哪几个古老的农田,然后对于剩下的空地,相邻空地之间建边,求一个二分图的最大独立集就是剩下的空地中最多能新建的农田数,再加上选出来的古老农田数就行了。
注意选出来的古老农田四周的空地不能建图,以避免新农田之间相连。
代码:
#include<bits/stdc++.h>using namespace std;const int MAXN = 110;int N, M;int mp[15][15];int go[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};int uN, vN;bool g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];bool dfs(int u){ for(int v = 1; v <= vN; v++) if(g[u][v] && !used[v]) { used[v] = 1; if(linker[v] == -1 || dfs(linker[v])) { linker[v] = u; return 1; } } return 0;}int hungary(){ int res = 0; memset(linker, -1, sizeof(linker)); for(int u = 1; u <= uN; u++) { memset(used, 0, sizeof used); if(dfs(u)) res++; } return res;}bool check(int status){int r, c;for(int i = 1; i <= N; i++){for(int j = 1; j <= M; j++){if(mp[i][j] == '.') continue;if(!(status >> mp[i][j] & 1)) continue;for(int k = 0; k < 4; k++){r = i + go[k][0];c = j + go[k][1];if(r < 1 || c < 1 || r > N || c > M) continue;if(mp[r][c] == '.' || mp[r][c] == mp[i][j]) continue;if(status >> mp[r][c] & 1) return 1;}}}return 0;}bool judge(int i, int j, int status){int r, c;for(int k = 0; k < 4; k++){r = i + go[k][0];c = j + go[k][1];if(r < 1 || c < 1 || r > N || c > M) continue;if(mp[r][c] == '.') continue;if(status >> mp[r][c] & 1) return 1;}return 0;}int solve(int status){int r, c, cnt = 0;uN = vN = N * M;memset(g, 0, sizeof(g));for(int i = 1; i <= N; i++){for(int j = 1; j <= M; j++){if(mp[i][j] != '.') continue;if(judge(i, j, status)) continue;cnt++;if((i + j) & 1) continue;for(int k = 0; k < 4; k++){r = i + go[k][0];c = j + go[k][1];if(r < 1 || c < 1 || r > N || c > M) continue;if(mp[r][c] != '.' || judge(r, c, status)) continue;g[(i - 1) * M + j][(r - 1) * M + c] = 1;}}}return cnt - hungary();}int bk[300], tid;int main(){//cout << (char)9; int T, r, c, x, y; cin >> T; for(int kase = 1; kase <= T; kase++) { tid = 0; memset(bk, -1, sizeof(bk)); scanf("%d %d", &N, &M); for(int i = 1; i <= N; i++) { for(int j = 1; j <= M; j++) { scanf(" %c", &mp[i][j]); if(mp[i][j] == '.') continue; if(bk[mp[i][j]] == -1) bk[mp[i][j]] = tid++; mp[i][j] = bk[mp[i][j]];}}int up = 1 << tid, ans = 0; for(int i = 0; i < up; i++) { if(check(i)) continue; ans = max(ans, solve(i) + __builtin_popcount(i));} printf("Case #%d: %d\n", kase, ans); }}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- CodeVS1519 过路费【Kruskal+倍增求LCA】
- 分类和逻辑回归(Classification and logistic regression)
- 数据库选择合适的数据类型
- 用双链表从尾端查找数据为什么会超时?
- 使用Hadoop和Spark实现二次排序
- HDU
- java消费者生产者问题
- 吴恩达mooc神经网络与深度学习
- 常用的一些git指令
- Python——在循环外使用else
- Python3 File(文件) 方法
- 在ArcGIS Online中创建三维图层和网络场景(2017.9)
- C语言实验——圆柱体计算
- 《着色器和屏幕特效》读书笔记第二章-表面着色器和纹理映射