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

时间:2022-08-29 08:59:32
这个题的数据,太卡了,TLE了两晚上,各种调试优化,各种蛋疼。

2756: [SCOI2012]奇怪的游戏

Time Limit: 40 Sec Memory Limit: 128 MB

Submit: 2311 Solved: 598

[Submit][Status][Discuss]

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

这道题一看到,还真没直接想到网络流,看了看每次必须找相邻两个点,偶然想到国际象棋,于是黑白染色;

于是统计出wnum,bnum,wsum,bsum(染成White的格子数,和初始的总数,及染成Black的格子数和初始总数)

二分最后的结果X(x为满足所有格子都一样时的格子中的数),所以可以得到下面的一个关系式:

         X * wnum - wsum = X * bnum - bsum
==> X * bnum - X * wnum = bsum - wsum
==> X = (bsum - wsum)/(bnum - wnum)

每次相邻两个+1可知,每次必然满足wsum+1,bsum+1;

所以我们得到 当 bnum==wnum 时,如果满足bsum!=wsum 则无解

当 bsum==wsum 时,如果x成立,则任何>=x的数都成立,所以二分X即可

当 bnum!=wnum 时,发现至多有一个解,所以解得X,判断是否符合即可

建图:

超级源S向每个白点连边,边权为X-white【i】;

每个白点向相邻的黑点连边,边权为INF;

每个黑点向超级汇T连边,边权为X-black【i】;

(X为二分出的值,white【】,black【】表示初始值)

用tot记录差值,判断最大流是否满足即可

值得注意的是这个题的 时间限制,以及long long。

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxl (1LL<<50)
#define zb(x,y) (x-1)*m+y
int dis[2005];
struct data{
int next,to;
long long v;
}edge[10005];
int cnt=1,head[2005]={0};
int q[2005],h,t;
int jz[50][50]={0};
int cur[2005];
int n,m,tim;
int wnum,bnum;
long long wsum,bsum;
int num;
int mx=0;
long long tot=0;
bool zt[50][50];
int move[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; void add(int u,int v,long long w)
{
cnt++;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].to=v;
edge[cnt].v=w;
} void insert(int u,int v,long long w)
{
add(u,v,w);add(v,u,0);
} 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;
} void init()
{
n=read(); m=read();
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
{
jz[i][j]=read();
zt[i][j]=(i+j)&1;
mx=max(mx,jz[i][j]);
}
num=n*m+1;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
if (zt[i][j]) {wnum++;wsum+=jz[i][j];}
else {bnum++;bsum+=jz[i][j];}
} void make(long long mv)
{
cnt=1;memset(head,0,sizeof(head));
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
if (zt[i][j])
{
insert(0,zb(i,j),mv-jz[i][j]);tot+=mv-jz[i][j];
for (int k=0; k<4; k++)
{
int x=i+move[k][0],y=j+move[k][1];
if (x>0 && x<=n && y>0 && y<=m)
insert(zb(i,j),zb(x,y),maxl);
}
}
else insert(zb(i,j),num,mv-jz[i][j]);
} bool bfs()
{
memset(dis,-1,sizeof(dis));
q[1]=0; dis[0]=1;
h=0;t=1;
while (h<t)
{
int j=q[++h],i=head[j];
while (i)
{
if (edge[i].v>0 && dis[edge[i].to]<0)
{
dis[edge[i].to]=dis[j]+1;
q[++t]=edge[i].to;
}
i=edge[i].next;
}
}
if (dis[num]>0)
return true;
else
return false;
} long long dfs(int loc,long long low)
{
if(loc==num)return low;
long long flow,cost=0;
for(int i=cur[loc];i;i=edge[i].next)
if(dis[edge[i].to]==dis[loc]+1)
{
flow=dfs(edge[i].to,min(low-cost,edge[i].v));
edge[i].v-=flow;edge[i^1].v+=flow;
if(edge[i].v) cur[loc]=i;
cost+=flow;if(cost==low)return low;
}
if(!cost)dis[loc]=-1;
return cost;
} long long dinic()
{
long long temp=0;
while (bfs())
{
for (int i=0; i<=num; i++) cur[i]=head[i];
temp+=dfs(0,maxl);
}
return temp;
} bool check(long long ans)
{
tot=0;
make(ans);
long long temp=dinic();
if (temp==tot) return 1;
return 0;
} int main()
{
tim=read();
while (tim--)
{
wnum=bnum=0;wsum=bsum=0;mx=0;
init();
if (wnum==bnum)
{
if (wsum!=bsum) {puts("-1");continue;}
long long left=mx;
long long right=maxl;
while (left<=right)
{
long long mid=(left+right)/2;
if (check(mid)) right=mid-1;
else left=mid+1;
}
printf("%lld\n",left*wnum-wsum);
}
else
{
long long x=(bsum-wsum)/(bnum-wnum);
if (x>=mx)
{
if (check(x)) {printf("%lld\n",(x*wnum)-wsum);continue;}
else puts("-1");
}
else puts("-1");
}
}
return 0;
}

BZOJ-2756 奇怪的游戏 黑白染色+最大流+当前弧优化+二分判断+分类讨论的更多相关文章

  1. bzoj 2756奇怪的游戏

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MB Description Blinke 最近喜欢上一个奇怪的游戏. 这个游戏 ...

  2. &lbrack;BZOJ 2756&rsqb; 奇怪的游戏

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2756 Algorithm: 比较新颖的题目 首先发现是对矩阵中相邻两数进行操作    & ...

  3. BZOJ 2756 奇怪的游戏(最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2756 题意:在一个 N*M 的棋盘上玩,每个格子有一个数.每次 选择两个相邻的格子,并使 ...

  4. BZOJ&period;2756&period;&lbrack;SCOI2012&rsqb;奇怪的游戏&lpar;二分 黑白染色 最大流ISAP&rpar;

    题目链接 \(Description\) \(Solution\) 这种题当然要黑白染色.. 两种颜色的格子数可能相同,也可能差1.记\(n1/n2\)为黑/白格子数,\(s1/s2\)为黑/白格子权 ...

  5. bzoj 1324 Exca王者之剑(黑白染色,最小割)

    [题意] 两相邻点不能同时选,选一个点集使得权值和最大. 出题人语文好... [思路] 将图进行黑白二染色,然后构建最小割模型. [代码] #include<set> #include&l ...

  6. bzoj 3240&colon; &lbrack;Noi2013&rsqb;矩阵游戏 矩阵乘法&plus;十进制快速幂&plus;常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

  7. BZOJ 2756 【SCOI2012】 奇怪的游戏

    题目链接:奇怪的游戏 一开始这道题想岔了……想到黑白染色后对总格子数按奇偶性分类讨论,然后没发现奇数个格子的可以直接解方程…… 首先可以发现每次操作是给相邻的两个格子权值加一,因此我们把棋盘黑白染色后 ...

  8. BZOJ 2756&colon; &lbrack;SCOI2012&rsqb;奇怪的游戏 &lbrack;最大流 二分&rsqb;

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

  9. BZOJ 2756 SCOI2012 奇怪的游戏 最大流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...

随机推荐

  1. application

    改变全局application到页面的参数 添加参数:HttpServletRequest req 使用req.getSession().getServletContext().setAttribut ...

  2. springMVC框架下——通用接口之图片上传接口

    我所想要的图片上传接口是指服务器端在完成图片上传后,返回一个可访问的图片地址. spring mvc框架下图片上传非常简单,如下 @RequestMapping(value="/upload ...

  3. Win8驱动测试模式

    打开驱动测试模式(保存成bat文件,双击执行) bcdedit /set testsigning on pause 执行完成后,看见提示操作成功的提示,之后我们重启一下,再次进入系统,在桌面的右下角会 ...

  4. socket基本操作

    我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠so ...

  5. 01背包之求第K优解——Bone Collector II

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解 ...

  6. C&plus;&plus;类的继承实例

    首先由三个类分别为DateType(日期类).TimeType(时间类).DateTimeType(日期时间内).详细代码例如以下: #include <iostream> using n ...

  7. Git—分支管理

    Git—分支管理 分支学习:branch称为分支,默认仅有一个名为master的分支.一般开发新功能流程为:开发新功能时会在分支dev上进行,开发完毕后再合并到master分支. branch相关常用 ...

  8. 导出IndoorGML

    导出IndoorGML

  9. js 防抖 debounce 与 节流 throttle

    debounce(防抖) 与 throttle(节流) 主要是用于用户交互处理过程中的性能优化.都是为了避免在短时间内重复触发(比如scrollTop等导致的回流.http请求等)导致的资源浪费问题. ...

  10. 缓存表 内存表&lpar;将表keep到内存&rpar;

    缓存表 内存表(将表keep到内存) 一.引言:     有时候一些基础表需要非常的频繁访问,尤其是在一些循环中,对该表中的访问速度将变的非常重要.为了提高系统的处理性能,可以考虑将一些表及索引读取并 ...