对棋盘黑白染色后,若n和m都是奇数(即白色和黑色点数不同),可以直接算得答案(根据白-黑不变);若n和m不都是奇数,二分答案(二分的上限要大一点,开$2^50$),最后都要用用网络流来判定。
考虑判定,将白色点放在左边,黑色点放在右边,源点流向白点的流量是白点与答案的差,黑点流向汇点的流量是黑点与答案的差,白点向每一个相邻的黑点流inf的边,判断是否满流即可。

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 2005
  4. 4 #define ll long long
  5. 5 #define inf (1LL<<50)
  6. 6 struct ji{
  7. 7 int nex,to;
  8. 8 ll len;
  9. 9 }edge[N*5];
  10. 10 queue<int>q;
  11. 11 int E,T,t,n,m,a[51][51],id[51][51],head[N],work[N],d[N];
  12. 12 ll l,r,s1,s2,mid;
  13. 13 void add(int x,int y,ll z){
  14. 14 edge[E].nex=head[x];
  15. 15 edge[E].to=y;
  16. 16 edge[E].len=z;
  17. 17 head[x]=E++;
  18. 18 if (E&1)add(y,x,0);
  19. 19 }
  20. 20 bool bfs(){
  21. 21 q.push(0);
  22. 22 memset(d,-1,sizeof(d));
  23. 23 d[0]=0;
  24. 24 while (!q.empty()){
  25. 25 int k=q.front();
  26. 26 q.pop();
  27. 27 for(int i=head[k];i!=-1;i=edge[i].nex)
  28. 28 if ((edge[i].len)&&(d[edge[i].to]<0)){
  29. 29 d[edge[i].to]=d[k]+1;
  30. 30 q.push(edge[i].to);
  31. 31 }
  32. 32 }
  33. 33 return d[T]>=0;
  34. 34 }
  35. 35 ll dfs(int k,ll s){
  36. 36 if (k==T)return s;
  37. 37 ll p;
  38. 38 for(int i=work[k];i!=-1;i=edge[i].nex)
  39. 39 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
  40. 40 p=dfs(edge[i].to,min(s,edge[i].len));
  41. 41 if (p){
  42. 42 edge[i].len-=p;
  43. 43 edge[i^1].len+=p;
  44. 44 work[k]=i;
  45. 45 return p;
  46. 46 }
  47. 47 }
  48. 48 work[k]=-1;
  49. 49 return 0;
  50. 50 }
  51. 51 ll dinic(){
  52. 52 ll k,ans=0;
  53. 53 while (bfs()){
  54. 54 memcpy(work,head,sizeof(head));
  55. 55 while (k=dfs(0,inf))ans+=k;
  56. 56 }
  57. 57 return ans;
  58. 58 }
  59. 59 bool pd(ll k){
  60. 60 memset(head,-1,sizeof(head));
  61. 61 E=0;
  62. 62 for(int i=1;i<=n;i++)
  63. 63 for(int j=1;j<=m;j++)
  64. 64 if ((i+j)&1){
  65. 65 add(0,id[i][j],k-a[i][j]);
  66. 66 if (i>1)add(id[i][j],id[i-1][j],inf);
  67. 67 if (j>1)add(id[i][j],id[i][j-1],inf);
  68. 68 if (i<n)add(id[i][j],id[i+1][j],inf);
  69. 69 if (j<m)add(id[i][j],id[i][j+1],inf);
  70. 70 }
  71. 71 else add(id[i][j],T,k-a[i][j]);
  72. 72 return dinic()==k*(n*m/2)-s1;
  73. 73 }
  74. 74 int main(){
  75. 75 scanf("%d",&t);
  76. 76 while (t--){
  77. 77 scanf("%d%d",&n,&m);
  78. 78 for(int i=1;i<=n;i++)
  79. 79 for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
  80. 80 for(int i=1;i<=n;i++)
  81. 81 for(int j=1;j<=m;j++)id[i][j]=(i-1)*m+j;
  82. 82 T=id[n][m]+1;
  83. 83 s1=s2=l=0;
  84. 84 for(int i=1;i<=n;i++)
  85. 85 for(int j=1;j<=m;j++){
  86. 86 l=max(l,1LL*a[i][j]);
  87. 87 if ((i+j)&1)s1+=a[i][j];
  88. 88 else s2+=a[i][j];
  89. 89 }
  90. 90 if ((n&1)&&(m&1)){
  91. 91 if ((s2-s1<l)||(!pd(s2-s1)))printf("-1\n");
  92. 92 else printf("%lld\n",(s2-s1)*(n*m/2)-s1);
  93. 93 continue;
  94. 94 }
  95. 95 if (s1!=s2){
  96. 96 printf("-1\n");
  97. 97 continue;
  98. 98 }
  99. 99 r=inf;
  100. 100 while (l<r){
  101. 101 mid=(l+r>>1);
  102. 102 if (pd(mid))r=mid;
  103. 103 else l=mid+1;
  104. 104 }
  105. 105 if (!pd(l))printf("-1\n");
  106. 106 else printf("%lld\n",l*n*m/2-s1);
  107. 107 }
  108. 108 }

[bzoj2756]奇怪的游戏的更多相关文章

  1. BZOJ-2756 奇怪的游戏 黑白染色+最大流+当前弧优化+二分判断+分类讨论

    这个题的数据,太卡了,TLE了两晚上,各种调试优化,各种蛋疼. 2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MB Submit ...

  2. 【bzoj2756 奇怪的游戏】

    Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 4403  Solved: 1226[Submit][Status][Discuss] Descript ...

  3. 【BZOJ2756】奇怪的游戏(二分,最小割)

    题意: Blinker最近喜欢上一个奇怪的游戏.这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻的格子,并使这两个数都加上 1.现在 Blinker 想知道最 ...

  4. 【BZOJ2756】奇怪的游戏(二分,网络流)

    [BZOJ2756]奇怪的游戏(二分,网络流) 题面 BZOJ Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blink ...

  5. 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2925  Solved: 792[Submit][Stat ...

  6. Bzoj2756 [SCOI2012]奇怪的游戏

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3220  Solved: 886 Description ...

  7. BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)

    Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...

  8. BZOJ2756 [SCOI2012]奇怪的游戏 【网络流 + 二分】

    题目 Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 Blinker 想知 ...

  9. bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)

    2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...

随机推荐

  1. 从零入门 Serverless | Serverless 应用如何管理日志 & 持久化数据

    作者 | 竞霄 阿里巴巴开发工程师 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 Se ...

  2. 干货 | 数据为王,携程国际火车票的 ShardingSphere 之路

    以下文章来源于携程技术 ,作者瑞华 作者简介 瑞华,携程高级后端开发工程师,关注系统架构.分库分表.微服务.高可用等. 一.前言 随着国际火车票业务的高速发展,订单量快速增长,单数据库瓶颈层面的问题逐 ...

  3. 技术番外篇丨Github Action CI/CD

    起源 看到.Net群里再聊CI/CD,我就这里分享一下我目前自己一些小东西的做法,我目前在Github有一个自己私有的组织,里面存放了我的部分商业化项目,早期我采用Jenkins用Webhooks进行 ...

  4. MC-BE基岩版服务器搭建与日常维护

    有部分内容被csdn和谐,强烈建议移步我的个人博客以获得更好的排版和阅读体验: xzajyjs.cn. 目录 环境搭建 开始部署 日常维护 服务器的白名单机制 定时备份 服务器升级 服务器模组安装 搭 ...

  5. 个人记录:对于python学习的反思和总结(一)

    在写代码时,总是遇到写着写着不知道怎么写了的情况,或者无法把自己的想法用程序表达出来,所以有时候我们需要建立一个自己的编程思路,对一个具体程序的编程有一个比较清晰的想法:因此我把自己的思路总结了一下, ...

  6. 【二食堂】Beta - 测试报告

    Beta - 测试报告 测试过程中发现的bug Beta阶段的新bug 我们在Beta阶段的开发过程中就进行了测试,发现了许多bug.这其中后端的bug比较多,在这里我列举一些比较重要的功能性bug. ...

  7. UltraSoft - Alpha - Postmortem 事后分析

    Alpha阶段 Postmortem会议 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 主要是解决DDL提醒功能的问题,定义的比较清楚,对典型用户和典 ...

  8. [no code][scrum meeting] Beta 5

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月18日14:30,主持者:叶开辉 下次例会时间:5月19日11:30,主持者:黎正宇 一.工作 ...

  9. 状压dp学习笔记(紫例题集)

    P3451旅游景点 Tourist Attractions 这个代码其实不算是正规题解的(因为我蒟蒻)是在我们的hzoj上内存限制324MIB情况下过掉的,而且经过研究感觉不太能用滚动数组,所以那这个 ...

  10. pyqgis环境配置

    配置pyqgis开发环境时,很多网上教程写的非常繁琐,这里仅仅找了一个最简单的配置方法,使用pycharm的IDE,安装QGIS软件后,在pycharm的ProjectInterpreter里面填写Q ...