解题报告 之 SOJ2835 Pick Up Points
来源:互联网 发布:电脑怎么恢复数据 编辑:程序博客网 时间:2024/06/06 02:13
解题报告 之 SOJ2835 Pick Up Points
Description
Description
Recently loy are very interested in playing a funny game. There is a board of n*m grid. Each grid has one point or not. If two adjacency grids both have one point, someone can pick them up, and then these two grids have no point. The two grids are adjacency only if the Manhattan distence between them is exactly 1. The purpose of the game is to gain as many points as possible.Input
The first line is an interger T, means the number of test cases. Each test case begins with two interger n,m (1 <= n,m <= 100), means the size of the board is n*m. Next n line, each line has m intergers which is 1 or 0, means the grid has one point or not.Output
Output the maximum point loy can get.Sample Input
23 40 1 0 10 1 1 01 1 1 12 21 00 1Sample Output
60Source
LOY
题目大意:题意非常简单,有一个n*m的棋盘,每个格子有1个或0个棋子,每次操作可以取走相邻的两个棋子(相邻意味着两个格子共享一条边)。问最多一共可以取走多少个棋子。
分析:我感觉挺难的,不过看过题数比其他题还高。。。醉了。这个是CFW模型(牛吃草喝水模型,见另一篇博文POJ 3281 Dining http://blog.csdn.net/maxichu/article/details/45190521 ),但是很难将此问题转化为牛吃草(反正我没想到)。
具体操作如下,将棋盘错开,i+j为奇数的格子为条件一(CFW模型中的F);i+j为偶数的格子为条件二(CFW模型中的D)。然后超级源点向所有条件一的点连一条边,负载为1。所有条件二的点向超级汇点连一条边,负载为1。那么超级汇点的最大流代表最大的配对数。然后要注意遍历所有点,如果它是条件一的点,则连一条边到它周围点(即4个条件二点,如果存在的话)。注意如果是条件二点则不能向周围连一条边,否则流量会错误转移(见图解)。然后跑最大流再乘以2即可。
注意到此时如果5<->2是都双向连接的话那么最大流从2变为3,错误!
上代码:
#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<cstdio>#include<sstream>#include<string>#include<cmath>using namespace std;const int MAXN = 20100;const int MAXM = 900000;const int INF = 0x3f3f3f3f;struct Edge{int from, to, cap, next;};Edge edge[MAXM];int level[MAXN];int map[150][150];int head[MAXN];int src, des, cnt = 0;void addedge( int from, int to, int cap ){edge[cnt].from = from;edge[cnt].to = to;edge[cnt].cap = cap;edge[cnt].next = head[from];head[from] = cnt++;swap( from, to );edge[cnt].from = from;edge[cnt].to = to;edge[cnt].cap = 0;edge[cnt].next = head[from];head[from] = cnt++;}int bfs( ){memset( level, -1, sizeof level );queue<int> q;while (!q.empty( ))q.pop( );level[src] = 0;q.push( src );while (!q.empty( )){int u = q.front( );q.pop( );for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap&&level[v] == -1){level[v] = level[u] + 1;q.push( v );}}}return level[des] != -1;}int dfs( int u, int f ){if (u == des) return f;int tem;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap&&level[v] == level[u] + 1){tem = dfs( v, min( f, edge[i].cap ) );if (tem > 0){edge[i].cap -= tem;edge[i ^ 1].cap += tem;return tem;}}}level[u] = -1;return 0;}int Dinic( ){int ans = 0, tem;while (bfs( )){while (tem = dfs( src, INF )){ans += tem;}}return ans;}int main( ){int kase, m, n;cin >> kase;src = 0; des = 20005;while (kase--){cin >> n>>m;memset( head, -1, sizeof head );cnt = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cin >> map[i][j];if (map[i][j]){if ((i + j) % 2 == 1)addedge( src, (i - 1) *100 + j, 1 );elseaddedge( (i - 1) * 100 + j, des, 1 );}}}for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){if (!map[i][j]) continue;if (i+1<=n&&map[i+1][j]){addedge( (i - 1) * 100 + j, i * 100 + j, 1 );}if (j + 1 <= m&&map[i][j+1]){addedge( (i - 1) * 100 + j, (i - 1) * 100 + j + 1, 1 );}if (i - 1 >= 1 && map[i-1][j]){addedge( (i - 1) * 100 + j, (i - 2) * 100 + j , 1 );}if (j - 1 >= 1 && map[i][j-1]){addedge( (i - 1) * 100 + j, (i - 1) * 100 + j - 1, 1 );}}}cout << Dinic() * 2 << endl;}return 0;}
嗯嗯就是这样,看来还是要继续修炼。编程之美好想要Azure的衣服啊!!
1 0
- 解题报告 之 SOJ2835 Pick Up Points
- FOJ 1467 Pick Up Points
- 解题报告 之 UVA11093 Just Finish it up
- [leetcode] 398. Random Pick Index 解题报告
- [Leetcode] 398. Random Pick Index 解题报告
- USACO Frame Up 解题报告
- pick up
- TCO10 whildcard 250points解题报告
- POJ 2403 Hay Points 解题报告
- POJ-3090-Visible Lattice Points 解题报告
- 1609 Tiling Up Blocks 解题报告
- POJ-3087 Shuffle'm Up 解题报告
- HDU 4619 Warm up 2 解题报告
- HDU 4612 Warm up 解题报告
- HNU 13081 Even Up Solitaire解题报告
- poj 1118 Lining Up 解题报告
- Leetcode 398. Random Pick Index 随机找位置 解题报告
- LeetCode—Max Points on a Line解题报告
- HTTP请求头和相应头的详细介绍
- [问题篇1]VMWare搭建Openstack——neutron agent-list的状态无效
- 文本分类(power 8算法挑战赛第五期)
- HDU1671 Phone List【字典树】
- 常用直方图匹配方法
- 解题报告 之 SOJ2835 Pick Up Points
- 百科网-跑龙套
- 在Eclipse中测试事务 的提交功能
- 黑马程序员——C语言知识点总结之结构体和枚举
- Eclipse下使用Ant
- Reducing the Dimensionality of Data with Neural Networks:神经网络用于降维
- git学习(一)
- Android事件总线EventBus详解
- Struts2中过滤器和拦截器的区别