Game

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1563    Accepted Submission(s): 664

Problem Description
onmylove has invented a game on n × m grids. There is one positive integer on each grid. Now you can take the numbers from the grids to make your final score as high as possible. The way to get score is like
the following:
● At the beginning, the score is 0;
● If you take a number which equals to x, the score increase x;
● If there appears two neighboring empty grids after you taken the number, then the score should be decreased by 2(x&y). Here x and y are the values used to existed on these two grids. Please pay attention that "neighboring grids" means there exits and only exits one common border between these two grids.

Since onmylove thinks this problem is too easy, he adds one more rule:
● Before you start the game, you are given some positions and the numbers on these positions must be taken away.
Can you help onmylove to calculate: what's the highest score onmylove can get in the game?

 
Input
Multiple input cases. For each case, there are three integers n, m, k in a line.
n and m describing the size of the grids is n ×m. k means there are k positions of which you must take their numbers. Then following n lines, each contains m numbers, representing the numbers on the n×m grids.Then k lines follow. Each line contains two integers, representing the row and column of one position
and you must take the number on this position. Also, the rows and columns are counted start from 1.
Limits: 1 ≤ n, m ≤ 50, 0 ≤ k ≤ n × m, the integer in every gird is not more than 1000.
 
Output
For each test case, output the highest score on one line.
 
Sample Input
2 2 1
2 2
2 2
1 1
2 2 1
2 7
4 1
1 1
 
Sample Output
4
9

Hint

As to the second case in Sample Input, onmylove gan get the highest score when calulating like this:
2 + 7 + 4 - 2 × (2&4) - 2 × (2&7) = 13 - 2 × 0 - 2 × 2 = 9.

 
Author
onmylove
 
Source
 
 
解析:
  棋盘问题的变形 多了点限制
  遇到这种问题就向最小割去想   最小割就是求最小价值损失
  对于预先选定的点 x   如果是白点 则 s 向 x 连一条INF的边  如果是黑点 则 x 向 t 连一条INF的边  因为权值为INF  所以无论怎样 这条边都不会成为割边 所以就能代表这条边已经被选择
  其它的就和棋盘问题一样  只不过相邻的点的边权   加了限制之后 把这条边的权值 由棋盘问题的INF 改为 2 * (w1 & w2)即可
跑一遍Dinic    然后sum - Dinic
#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define rb(a) scanf("%lf", &a)
#define rf(a) scanf("%f", &a)
#define pd(a) printf("%d\n", a)
#define plld(a) printf("%lld\n", a)
#define pc(a) printf("%c\n", a)
#define ps(a) printf("%s\n", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1e5 + , INF = 0x7fffffff;
int dir[][] = {{, }, {, -}, {, }, {-, }};
int n, m, k, s, t;
int way[][], vv[][];
int head[maxn], cur[maxn], vis[maxn], d[maxn], cnt, nex[maxn << ]; struct node
{
int u, v, c;
}Node[maxn << ]; void add_(int u, int v, int c)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].c = c;
nex[cnt] = head[u];
head[u] = cnt++;
} void add(int u, int v, int c)
{
add_(u, v, c);
add_(v, u, );
} bool bfs()
{
queue<int> Q;
mem(d, );
Q.push(s);
d[s] = ;
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = head[u]; i != -; i = nex[i])
{
int v = Node[i].v;
if(!d[v] && Node[i].c > )
{
d[v] = d[u] + ;
Q.push(v);
if(v == t) return ;
}
}
}
return d[t] != ;
} int dfs(int u, int cap)
{
int ret = ;
if(u == t || cap == )
return cap;
for(int &i = cur[u]; i != -; i = nex[i])
{
int v = Node[i].v;
if(d[v] == d[u] + && Node[i].c > )
{
int V = dfs(v, min(cap, Node[i].c));
Node[i].c -= V;
Node[i ^ ].c += V;
ret += V;
cap -= V;
if(cap == ) break;
}
}
if(cap > ) d[u] = -;
return ret;
} int Dinic()
{
int ans = ;
while(bfs())
{
memcpy(cur, head, sizeof head);
ans += dfs(s, INF);
}
return ans;
} int main()
{
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
int sum = ;
s = , t = n * m + ;
mem(head, -), cnt = , mem(vv, );
int w, x, y;
rap(i, , n)
rap(j, , m)
rd(way[i][j]), sum += way[i][j];
rap(i, , k)
{
rd(x), rd(y);
if((x + y) & )
add(s, (x - ) * m + y, INF);
else add((x - ) * m + y, t, INF);
vv[x][y] = ;
}
rap(i, , n)
rap(j, , m)
{
rep(k, , )
{
int nx = i + dir[k][];
int ny = j + dir[k][];
if(nx < || ny < || nx > n || ny > m) continue;
if((i + j) & )
add((i - ) * m + j, (nx - ) * m + ny, * (way[i][j] & way[nx][ny]));
}
if(vv[i][j]) continue;
if((i + j) & ) add(s, (i - ) * m + j, way[i][j]);
else add((i - ) * m + j, t, way[i][j]);
}
cout << sum - Dinic() << endl; } return ;
}
  
 

Game

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1563    Accepted Submission(s): 664

Problem Description
onmylove has invented a game on n × m grids. There is one positive integer on each grid. Now you can take the numbers from the grids to make your final score as high as possible. The way to get score is like
the following:
● At the beginning, the score is 0;
● If you take a number which equals to x, the score increase x;
● If there appears two neighboring empty grids after you taken the number, then the score should be decreased by 2(x&y). Here x and y are the values used to existed on these two grids. Please pay attention that "neighboring grids" means there exits and only exits one common border between these two grids.

Since onmylove thinks this problem is too easy, he adds one more rule:
● Before you start the game, you are given some positions and the numbers on these positions must be taken away.
Can you help onmylove to calculate: what's the highest score onmylove can get in the game?

 
Input
Multiple input cases. For each case, there are three integers n, m, k in a line.
n and m describing the size of the grids is n ×m. k means there are k positions of which you must take their numbers. Then following n lines, each contains m numbers, representing the numbers on the n×m grids.Then k lines follow. Each line contains two integers, representing the row and column of one position
and you must take the number on this position. Also, the rows and columns are counted start from 1.
Limits: 1 ≤ n, m ≤ 50, 0 ≤ k ≤ n × m, the integer in every gird is not more than 1000.
 
Output
For each test case, output the highest score on one line.
 
Sample Input
2 2 1
2 2
2 2
1 1
2 2 1
2 7
4 1
1 1
 
Sample Output
4
9

Hint

As to the second case in Sample Input, onmylove gan get the highest score when calulating like this:
2 + 7 + 4 - 2 × (2&4) - 2 × (2&7) = 13 - 2 × 0 - 2 × 2 = 9.

 
Author
onmylove
 
Source
 

Game HDU - 3657(最小割)的更多相关文章

  1. hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割

    题意:方格取数,如果取了相邻的数,那么要付出一定代价.(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪...) 建图:  对于相邻问题,经典方法:奇偶建立二分图.对于相邻两点连边2 ...

  2. hdu 3657 最小割(牛逼!!!!)总算理解了

    <strong></strong> 转载:http://blog.csdn.net/me4546/article/details/6662959 加颜色的太棒了!!! 在网上看 ...

  3. hdu 4289(最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 思路:求最小花费,最小割应用,将点权转化为边权,拆点,(i,i+n)之间连边,容量为在城市i的花 ...

  4. hdu 5076 最小割灵活运用

    这意味着更复杂的问题,关键的事实被抽象出来:每个点,能够赋予既有的值(挑两个一.需要选择,设定ai,bi). 寻找所有和最大.有条件:如果两个点同时满足: 1,:二进制只是有一个不同之处.  2:中的 ...

  5. hdu 1565 最小割

    黑白染色,源指向白,黑指向汇,容量都是方格中数的大小,相邻的格子白指向黑,容量为oo,然后求一次最小割. 这个割是一个简单割,如果只选择不在割中的点,那么一种割就和一个选数方案一一对应,割的大小就是不 ...

  6. Being a Hero (hdu 3251 最小割 好题)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  7. hdu 3691最小割将一个图分成两部分

    转载地址:http://blog.csdn.net/xdu_truth/article/details/8104721 题意:题给出一个无向图和一个源点,让你求从这个点出发到某个点最大流的最小值.由最 ...

  8. [HDU 3521] [最小割] Being a Hero

    题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And  m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...

  9. hdu 1569 最小割

    和HDU 1565是一道题,只是数据加强了,貌似轮廓线DP来不了了. #include <cstdio> #include <cstring> #include <que ...

随机推荐

  1. 微信小程序页面跳转方法总结

    微信小程序页面跳转目前有以下方法(不全面的欢迎补充): 1. 利用小程序提供的 API 跳转: // 保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面.// 注 ...

  2. Bootstrap 栅格 样式 组件 插件

    -----------------------------起先是我们造成习惯,后来是习惯造成我们. day 51 Bootstrap  官方网站:   bootcss.com/ <!DOCTYP ...

  3. find和grep命令合集

    linux grep命令 1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expressi ...

  4. Python练习-2

    #1.使用while循环输入 1 2 3 4 5 6 8 9 10 count = 0 while count < 10: count += 1 # count = count + 1 if c ...

  5. group by用法

    select * from Table group by id,一定不能是*,而是某一个列或者某个列的聚合函数. 参考:http://www.cnblogs.com/jingfengling/p/59 ...

  6. 关于标准的知识 GB ISO 等内容

    1. 来自百度知道: GB:GB 即"国标"的汉语拼音缩写,为中华人民共和国国家标准的意思. ISO:国际标准化组织的英语简称.其全称是International Organiza ...

  7. [转帖]TLS 1.3 VS TLS 1.2,让你明白 TLS 1.3 的强大

    TLS 1.3 VS TLS 1.2,让你明白 TLS 1.3 的强大 https://www.jianshu.com/p/efe44d4a7501?utm_source=oschina-app 又拍 ...

  8. vue页面是否缓存的两种方式

    第一种 <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> ...

  9. Js中instanceof 的用法

    在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”. ...

  10. Handler主线程子线程之间的互相通信

    Handler主线程子线程之间的互相通信 package com.wyl.dansnote; import android.app.Activity; import android.os.Bundle ...