bzoj2756 [SCOI2012]奇怪的游戏
来源:互联网 发布:约瑟夫环的数组实现 编辑:程序博客网 时间:2024/05/17 01:48
Description
Blinker最近喜欢上一个奇怪的游戏。
这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻
的格子,并使这两个数都加上 1。
现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同
一个数则输出-1。
Input
输入的第一行是一个整数T,表示输入数据有T轮游戏组成。
每轮游戏的第一行有两个整数N和M, 分别代表棋盘的行数和列数。
接下来有N行,每行 M个数。
Output
对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出-1。
Sample Input
2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2
Sample Output
2
-1
HINT
【数据范围】
对于30%的数据,保证 T<=10,1<=N,M<=8
对于100%的数据,保证 T<=10,1<=N,M<=40,所有数为正整数且小于1000000000
Source
http://cxjyxx.me/?p=223
cxjyxx_me:
Blinker最近喜欢上一个奇怪的游戏。
这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻
的格子,并使这两个数都加上 1。
现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同
一个数则输出-1。
对棋盘进行黑白染色
设黑格个数为num1 数值和为sum1
设白格个数为num1 数值和为sum1
设最后都变为x
则
num1 * x – sum1 = num2 * x – sum2
x = (sum1 – sum2) / (num1 – num2)
当num1 ≠ num2时 可以解出 x 再用网络流check即可
对于num1 = num2时 可以发现 对于一个合法的x k>=x都是一个合法的解
因为num1 = num2 => (num1 + num2) % 2 == 0 可以构造一层的满覆盖
所以可以二分x 然后用网络流check
建图:
如果点k为白
建边(s, k, x – v[k])
如果为黑
建边(k, t, x – v[k])
对相邻点u、v (u为白)
建边 (u, v, inf)
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<set>#include<ctime>#include<vector>#include<queue>#include<algorithm>#include<map>#include<cmath>#define M 20005#define inf (1LL<<50)#define pa pair<int,int>#define ll long long #define p(x,y) (x-1)*m+yusing namespace std;inline int read(){ int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch-'0'; ch = getchar(); } return x * f;}ll s0,s1;int c0,c1;int test,n,m,cnt,S,T;int xx[4] = {0, 0, 1, -1};int yy[4] = {1, -1, 0, 0};int a[45][45];int head[2005],h[2005],q[2005],cur[2005];bool color[45][45];struct edge{ int to, next; ll v;}e[20005];void ins(int u, int v, ll w){ e[++ cnt].next = head[u]; head[u] = cnt; e[cnt].to = v; e[cnt].v = w;}void insert(int u, int v, ll w){ ins(u, v, w); ins(v, u, 0);}ll dfs(int x, ll f){ if(x == T) return f; ll used = 0, w; for(int i = head[x]; i; i = e[i].next) { int y = e[i].to; if(h[y] == h[x] + 1 && e[i].v) { w = dfs(y, min(e[i].v, f - used)); e[i].v -= w; if(e[i].v) cur[x] = i; e[i^1].v += w; used += w; if(f == used) return f; } } if(used == 0) h[x] = -1; return used;}int bfs(){ int t = 0, w = 1; memset(h, -1, sizeof(h)); q[0] = S; h[S] = 0; while(t != w) { int now = q[t ++]; if(t == M) t = 0; for(int i = head[now]; i; i = e[i].next) { int y = e[i].to; if(h[y] == -1 && e[i].v) { h[y] = h[now] + 1; q[w ++] = y; if(w == M) w = 0; } } } if(h[T] == -1) return 0; else return 1;}ll dinic(){ ll ans = 0ll; while(bfs()) { for(int i = S; i <= T; i ++) cur[i] = head[i]; ans += dfs(S, inf); } return ans;}bool check(ll x){ memset(head,0,sizeof(head)); cnt = 1; S = 0; T = n * m + 1; ll tot = 0; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) if(color[i][j]) { insert(S, p(i,j), x - a[i][j]); tot += x - a[i][j]; for(int k = 0; k < 4; k ++) { int nowx = i + xx[k], nowy = j + yy[k]; if(nowx < 1 || nowy < 1 || nowx > n || nowy > m)continue; insert(p(i, j), p(nowx, nowy), inf); } } else insert(p(i, j), T, x - a[i][j]); if(dinic() == tot)return 1; return 0;}int main(){ test = read(); while(test --) { c0 = c1 = s0 = s1 = 0; n = read(); m = read(); int mx = 0; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) { a[i][j] = read(), color[i][j] = (i + j) & 1; mx = max(mx, a[i][j]); } for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) if(color[i][j]) s1 += a[i][j], c1 ++; else s0 += a[i][j], c0 ++; if(c0 != c1) { ll x = (s0 - s1) / (c0 - c1); if(x >= mx) if(check(x)) { printf("%lld\n",x * c1 - s1); continue; } puts("-1"); } else { ll l = mx, r = inf; while(l <= r) { ll mid = (l + r) >> 1; if(check(mid)) r = mid - 1; else l = mid + 1; } printf("%lld\n",(ll)l * c1 - s1); } } return 0;}
- bzoj2756: [SCOI2012]奇怪的游戏
- [BZOJ2756][SCOI2012]奇怪的游戏
- BZOJ2756/SCOI2012 奇怪的游戏
- bzoj2756 [SCOI2012]奇怪的游戏
- bzoj2756 [SCOI2012]奇怪的游戏
- bzoj2756 [SCOI2012]奇怪的游戏
- 【SCOI2012】bzoj2756 奇怪的游戏
- bzoj2756 [SCOI2012]奇怪的游戏
- BZOJ2756 [SCOI2012]奇怪的游戏
- 【BZOJ2756】【SCOI2012】奇怪的游戏 最大流、
- 【二分+最大流】[SCOI2012]奇怪的游戏 BZOJ2756
- bzoj2756: [SCOI2012]奇怪的游戏 二分+最大流
- 【最大流】【二分】[Scoi2012] bzoj2756 奇怪的游戏
- 【bzoj2756】【SCOI2012】【奇怪的游戏】【最大流+二分】
- BZOJ2756 【scoi2012】奇怪的游戏(二分+网络流)
- bzoj2756[SCOI2012]奇怪的游戏 二分 分类讨论 最大流
- 【bzoj2756: [SCOI2012]奇怪的游戏】 二分+网络流判断
- SCOI2012[奇怪的游戏]
- NSOperationQueue+NSBlockOPeration实例,下载合成图片
- CocoaPods安装使用及配置私有库
- 关于block的使用
- Spring MVC 集成 Apache Shiro权限控制-测试可行
- Swift在导航栏左侧或者右侧放置多个按钮
- bzoj2756 [SCOI2012]奇怪的游戏
- 我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
- AllJoyn核心应用教程【第三章】:接口编写与信号设置
- 最新苹果开发者账号注册流程详解
- SGU 120 Archipelago(计算几何)
- PSR-0标准
- scrpy 豆瓣电影信息爬取
- NSOperation创建的三种方式
- ImageLoader加载本地图片的实现————防OOM