HDU 1569 方格取数(2) 最大点权独立集
2016-11-05 20:04
330 查看
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1569题意:
Problem Description给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
Output
对于每个测试实例,输出可能取得的最大的和
思路:
hdu 1565的升级版,数据范围变大了一点,还有不是n*n的方格了,而是n*m的方格,代码稍微改一下救过了#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <set> #include <cmath> using namespace std; typedef long long ll; const int N = 3010, INF = 0x3f3f3f3f; struct edge { int to, cap, next; }g[N*300]; int cnt, head ; int gap , que , level , pre , cur ; int ss, tt, nv; void add_edge(int v, int u, int cap) { g[cnt].to = u, g[cnt].cap = cap, g[cnt].next = head[v], head[v] = cnt++; g[cnt].to = v, g[cnt].cap = 0, g[cnt].next = head[u], head[u] = cnt++; } void bfs(int t) { memset(level, -1, sizeof level); memset(gap, 0, sizeof gap); int st = 0, en = 0; level[t] = 0; que[en++] = t; gap[level[t]]++; while(st < en) { int v = que[st++]; for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(level[u] < 0) { level[u] = level[v] + 1; gap[level[u]]++; que[en++] = u; } } } } int sap(int s, int t) { bfs(t); memcpy(cur, head, sizeof head); int v = pre[s] = s, flow = 0, aug = INF; while(level[s] < nv) { bool flag = false; for(int &i = cur[v]; i != -1; i = g[i].next) { int u = g[i].to; if(g[i].cap > 0 && level[v] == level[u] + 1) { flag = true; pre[u] = v; v = u; aug = min(aug, g[i].cap); if(v == t) { flow += aug; while(v != s) { v = pre[v]; g[cur[v]].cap -= aug; g[cur[v]^1].cap += aug; } aug = INF; } break; } } if(flag) continue; int minlevel = nv; for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(g[i].cap > 0 && level[u] < minlevel) minlevel = level[u], cur[v] = i; } if(--gap[level[v]] == 0) break; level[v] = minlevel + 1; gap[level[v]]++; v = pre[v]; } return flow; } int main() { int n, m; while(~ scanf("%d%d", &n, &m)) { cnt = 0; memset(head, -1, sizeof head); int arr[60][60]; ss = 0, tt = n * m + 1; int sum = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { scanf("%d", &arr[i][j]); sum += arr[i][j]; if((i + j) % 2 == 0) { add_edge(ss, (i-1)*m + j, arr[i][j]); if(i != 1) add_edge((i-1)*m + j, (i-2)*m + j, INF); if(i != n) add_edge((i-1)*m + j, i*m + j, INF); if(j != 1) add_edge((i-1)*m + j, (i-1)*m + j - 1, INF); if(j != m) add_edge((i-1)*m + j, (i-1)*m + j + 1, INF); } else add_edge((i-1)*m + j, tt, arr[i][j]); } nv = tt + 1; printf("%d\n", sum - sap(ss, tt)); } return 0; }
相关文章推荐
- hdu 1569 方格取数(2) 网络流--最大点权独立集
- hdu 1569 方格取数(2) 最大权独立集
- HDU 1569 方格取数(2)(最大独立点集)
- 【HDU 1569】 方格取数2 --最大点权独立集
- hdu 1569 方格取数(2) 网络流 最大点权独立集
- hdu 1569 方格取数(2) 最大点权独立集
- HDU 1569 方格取数(2) 最大点权独立集
- hdu 1569 方格取数(2) 最大点权独立集
- 独立最小【网络流第五弹】最大点权独立集 ——HDU 1569 方格取数(2)
- hdu 1569 方格取数(2)【最大权独立集合-------最大流Edmond_Karp】
- hdu 1569 方格取数——最大点权独立集
- hdu 1569 最大点权独立集
- hdu 1569 方格取数 最大点权独立集(hdu 1565)
- hdu 1565 方格取数 最大点权独立集
- hdu1565方格取数(1) 最大流之 最大点权独立集
- hdu 1565 方格取数(1)(最小割--最大权独立点集)
- hdu-1569(网络流)-最大点权独立集
- hdu 1569 方格取数(2)--最大点权独立集-->最大流
- HDU 1569 方格取数(2)(最大点权独立集)
- HDU 1569 最大点权独立集