BZOJ2756/SCOI2012 奇怪的游戏
来源:互联网 发布:彩影软件 arp 编辑:程序博客网 时间:2024/06/08 07:00
思路:
首先网络流在网格上经常用到黑白染色。其次如果涉及到一些平衡(相等之类)经常可以列流量平衡方程方程求解。
hzwer有很好的题解。这里只是贴代码。
/************************************************************** Problem: 2756 User: DtenSherlock Language: C++ Result: Accepted Time:12568 ms Memory:2888 kb****************************************************************/#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<cstring>#include<string>#include<queue>using namespace std;typedef long long LL;const int imax=40+9;const int dmax=2290;const int bmax=100000+229;const LL inf=1LL<<61;const int dx[4]={0,0,1,-1};const int dy[4]={1,-1,0,0};int TT,n,m,id[imax][imax],tot; LL a[imax][imax];int S,T,num,head[dmax],to[bmax],inext[bmax]; LL re[bmax];void iread(){ scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]),id[i][j]=++tot;}int d[dmax]; queue<int>q;bool BFS(){ memset(d,0,sizeof(d)); q.push(S); d[S]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=inext[i]) if(re[i] && !d[to[i]]) { d[to[i]]=d[u]+1; q.push(to[i]); } } return d[T]>0;}LL DFS(int x,LL c){ if(x==T || c==0) return c; LL r=c; for(int i=head[x];i!=-1;i=inext[i]) if(d[to[i]]==d[x]+1) { LL f=DFS(to[i],min(re[i],r)); r-=f; re[i]-=f; re[i^1]+=f; if(!r) break; } if(r==c) d[x]=0; return c-r; }void iadd(int u,int v,LL flow){ to[num]=v; re[num]=flow; inext[num]=head[u]; head[u]=num++;}void add(int u,int v,LL flow) { iadd(u,v,flow); iadd(v,u,0);}bool pd(LL delta){ S=0; T=n*m+1; for(int i=S;i<=T;i++) head[i]=-1; num=0; LL sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((i+j)&1) add(S,id[i][j],delta-a[i][j]),sum+=delta-a[i][j]; else add(id[i][j],T,delta-a[i][j]); if(!((i+j)&1)) continue; for(int k=0;k<4;k++) { int nowx=i+dx[k]; int nowy=j+dy[k]; if(nowx<1 || nowx>n || nowy<1 || nowy>m) continue; add(id[i][j],id[nowx][nowy],inf); } } LL nowans=0; while(BFS()) nowans+=DFS(S,inf); return (nowans==sum);}void iwork(){ LL sum1=0; LL sum2=0; LL Max=0; int num1=0; int num2=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((i+j)&1) num1++,sum1+=a[i][j]; else num2++,sum2+=a[i][j]; Max=max(Max,a[i][j]); } if(num1!=num2) { LL x=(sum1-sum2)/(num1-num2); if(x>=Max) { if(pd(x)) { printf("%lld\n",(x*num1-sum1)); return; } } puts("-1"); } else { LL l=Max; LL r=inf; while(l<=r) { // printf("%lld %lld\n",l,r); if(l+1==r || l==r) { if(pd(l)) r=l; break; } LL Mid=(l+r)>>1; if(pd(Mid)) r=Mid; else l=Mid+1; } if(pd(r)) { printf("%lld\n",r*num1-sum1); return;} puts("-1"); }}int main(){ scanf("%d",&TT); while(TT--) { iread(); iwork(); } return 0;}
0 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[奇怪的游戏]
- PAT-A1049. Counting Ones (30)
- android日常开发总结技术60条
- Y460安装桌面导航
- typedef之函数
- 基于Spark的异构分布式深度学习平台
- BZOJ2756/SCOI2012 奇怪的游戏
- PAT-A1081. Rational Sum (20)
- 普里姆算法与迪杰斯特拉算法
- Java复习(1)-字符串,switch,数组
- 提高 Android 代码质量的4个工具
- Java标识符命名。。。
- 蓝桥杯-十六进制转八进制
- Emmet使用技巧
- POJ 2723 Get Luffy Out(2-SAT)