【BZOJ 2756】[SCOI2012]奇怪的游戏 网络流+二分
来源:互联网 发布:淘宝添加到桌面没有了 编辑:程序博客网 时间:2024/05/01 20:43
很有趣的做法。
首先,题目要求每一次的加数都必须加相邻的两个格子,这样我们将棋盘黑白染色就能很显然的发现每一次的加数都是将一个黑格子和一个白格子加一。
继续分析:设黑格子的个数为c1,和为s1,白格子的个数为c2,和为s2,设最后棋盘所有数字为x
x*c1-s1=x*c2-s2
x=(s1-s2)/(c1-c2)
1.c1!=c2直接网络流判断
2.c1!=c2显然如果棋盘现在所有数为x,由于c1==c2所以可以将每个格子都再加一,也就是说满足单调性,这样就可以二分了。
最后网络流怎么判呢?很简单
s->黑格子,权值为x-val 白格子->t权值为x-val 黑白之间连边,权值为inf,最后判断是否满流就好了
#include<cstdio>#include<cstring>#include<iostream>#define maxn 162121#define inf 36028797018963967ll#define LL long longusing namespace std;const int dx[]={-1,0,0,1};const int dy[]={0,1,-1,0};int T,last[maxn],head[1641],n,m,tot,h[maxn],nu[41][41],vis[41][41];int s,t,q[maxn];LL mat[41][41];struct edge{int v,next;LL w;}e[maxn];void adde(int a,int b,LL c){e[tot].v=b,e[tot].next=head[a],e[tot].w=c;head[a]=tot++;e[tot].v=a,e[tot].next=head[b],e[tot].w=0;head[b]=tot++;} bool bfs(){for(int i=s;i<=t;i++)h[i]=-1;h[s]=0;q[0]=s;int l=0,r=1;while(l<r){int u=q[l++];for(int v,i=head[u];i!=-1;i=e[i].next)if(h[v=e[i].v]==-1&&e[i].w){h[v]=h[u]+1;q[r++]=v;}}return h[t]!=-1;}LL dfs(int u,LL f){if(!f||u==t)return f;LL used=0,w;for(int v,i=last[u];i!=-1;i=e[i].next)if(h[v=e[i].v]==h[u]+1&&e[i].w){w=min(f-used,e[i].w);last[u]=i;w=dfs(v,w);used+=w;e[i].w-=w,e[i^1].w+=w;if(used==f)return f;}if(!used)h[u]=-1;return used;}LL dinic(){LL ans=0;while(bfs()){for(int i=s;i<=t;i++)last[i]=head[i];ans+=dfs(s,inf);}return ans;}bool cheak(LL x){tot=0;s=0,t=n*m+1;LL ans=0;memset(head,-1,sizeof(head));for(int id,i=1;i<=n;i++){for(int j=1;j<=m;j++){id=nu[i][j];if(vis[i][j]){ans+=x-mat[i][j];adde(s,nu[i][j],x-mat[i][j]);for(int x,y,k=0;k<4;k++){x=i+dx[k],y=j+dy[k];if(x<1||x>n||y<1||y>m)continue;adde(id,nu[x][y],inf);}}else adde(id,t,x-mat[i][j]);}}return ans==dinic();}void solve(){LL s1=0,c1=0,s2=0,c2=0,x=0,mx=0;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%lld",&mat[i][j]);mx=max(mx,mat[i][j]);vis[i][j]=i+j&1;nu[i][j]=(i-1)*m+j;if(vis[i][j])c1++,s1+=mat[i][j];else c2++,s2+=mat[i][j];}}if(c1!=c2){x=(s1-s2)/(c1-c2);if(x>=mx&&cheak(x))printf("%lld\n",x*c1-s1);else puts("-1");}else{if(s1!=s2)puts("-1");else{LL l=mx,r=inf;while(l<r){LL mid=l+r>>1ll;if(cheak(mid))r=mid;else l=mid+1;}printf("%lld\n",l*c1-s1);}}}int main(){scanf("%d",&T);while(T--)solve();return 0;}
0 0
- bzoj 2756: [SCOI2012]奇怪的游戏(网络流+二分)
- 【BZOJ 2756】[SCOI2012]奇怪的游戏 网络流+二分
- BZOJ 2756 [SCOI2012]奇怪的游戏 二分+网络流
- BZOJ2756 【scoi2012】奇怪的游戏(二分+网络流)
- 【bzoj2756: [SCOI2012]奇怪的游戏】 二分+网络流判断
- BZOJ 2756 [SCOI2012]奇怪的游戏
- BZOJ 2756 [SCOI2012]奇怪的游戏
- BZOJ 2756 SCOI2012 奇怪的游戏
- Dinic最大流(bzoj 2756: [SCOI2012]奇怪的游戏)
- [SCOI2012]奇怪的游戏 (网络流)
- BZOJ P2756[SCOI2012]奇怪的游戏
- 【最大流】【二分检验】【SCOI2012】奇怪的游戏
- 【二分+最大流】[SCOI2012]奇怪的游戏 BZOJ2756
- bzoj2756: [SCOI2012]奇怪的游戏 二分+最大流
- 【最大流】【二分】[Scoi2012] bzoj2756 奇怪的游戏
- 【bzoj2756】【SCOI2012】【奇怪的游戏】【最大流+二分】
- bzoj2756[SCOI2012]奇怪的游戏 二分 分类讨论 最大流
- 2756: [SCOI2012]奇怪的游戏
- 图解Activity的启动过程
- Web前端-JS效果-导航弹框、背景变色、鼠标移动切换等常见的js效果
- cannot open shared object file: No such file or directory
- web Servlet
- ubuntu深度学习框架Matconvnet与caffe搭建 (Ubuntu14.04+Cuda7.5+Cudnn5+Matlab2015b
- 【BZOJ 2756】[SCOI2012]奇怪的游戏 网络流+二分
- mysql建立索引
- 内存被错误改变,越界写的分析
- VoIP技术(3)-语音编码算法
- Leetcode刷题记——48. Rotate Image(旋转图像)
- douglas peucker递归分治
- 【问题解决】Eclipse安装Aptana插件-(注意对应版本问题)
- 在2017年,如何将你的小米4刷上Windows 10 mobile?(后附大量图赏)
- Android动画