首页 > 代码库 > BZOJ 2756 奇怪的游戏
BZOJ 2756 奇怪的游戏
1.二分+网络流+各种判。
2.网上很多程序都是错的。
3.一个%lld打成%d调了一年。
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#define maxn 45#define maxv 1700#define maxe 1000500#define inf (1LL<<50)using namespace std;long long tt,n,m,map[maxn][maxn],col[maxn][maxn],n1=0,n2=0,s1=0,s2=0,mx=0;long long dx[]={0,0,1,0,-1},dy[]={0,1,0,-1,0};long long dis[maxv],nume=1,g[maxv],s,t;queue <long long> q;bool vis[maxv];struct edge{ long long v,f,nxt;}e[maxe];long long p(long long x,long long y){ return (x-1)*m+y;}void addedge(long long u,long long v,long long f){ e[++nume].v=v;e[nume].f=f;e[nume].nxt=g[u];g[u]=nume; e[++nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume;}bool checks(long long x,long long y){ if ((x>=1) && (x<=n) && (y>=1) && (y<=m)) return true; return false;}void build(long long x){ nume=1;memset(g,0,sizeof(g)); s=0;t=n1+n2+1; for (long long i=1;i<=n;i++) for (long long j=1;j<=m;j++) { long long now=p(i,j); if (col[i][j]) addedge(s,now,x-map[i][j]); else addedge(now,t,x-map[i][j]); if (col[i][j]) { for (long long k=1;k<=4;k++) { long long a=i+dx[k],b=j+dy[k],ret=p(a,b); if (checks(a,b)) addedge(now,ret,inf); } } }}bool bfs(){ for (long long i=s;i<=t;i++) {dis[i]=inf;vis[i]=false;} q.push(s);dis[s]=0;vis[s]=true; while (!q.empty()) { long long head=q.front();q.pop(); for (long long i=g[head];i;i=e[i].nxt) { long long v=e[i].v; if ((e[i].f) && (dis[v]>dis[head]+1)) { dis[v]=dis[head]+1; if (!vis[v]) {q.push(v);vis[v]=true;} } } } if (dis[t]==inf) return false; return true;}long long dinic(long long x,long long low){ if (x==t) return low; long long ret=0; for (long long i=g[x];i && low;i=e[i].nxt) { long long v=e[i].v; if ((e[i].f) && (dis[v]==dis[x]+1)) { long long dd=dinic(v,min(e[i].f,low)); e[i].f-=dd;e[i^1].f+=dd; ret+=dd;low-=dd; } } if (!ret) dis[x]=inf; return ret;}bool check(long long x){ build(x); long long max_flow=0,ret=0; while (bfs()) max_flow+=dinic(s,inf); for (long long i=1;i<=n;i++) for (long long j=1;j<=m;j++) if (col[i][j]) ret+=(x-map[i][j]); if (ret==max_flow) return true; return false;}void work1(){ long long x=(s1-s2)/(n1-n2); if (x>=mx) if (check(x)) { long long ret=x*(n1+n2)-s1-s2; printf("%lld\n",(x*(n1+n2)-s1-s2)/2); return; } printf("-1\n");}void work2(){ if (s1!=s2) {printf("-1\n");return;} long long l=mx,r=inf,ans=inf; while (l<=r) { long long mid=l+r>>1; if (check(mid)) {ans=mid;r=mid-1;} else l=mid+1; } if (ans==inf) printf("-1\n"); else printf("%lld\n",(ans*(n1+n2)-s1-s2)/2); return;}void work(){ n1=0;n2=0;s1=0;s2=0;mx=0; scanf("%lld%lld",&n,&m); for (long long i=1;i<=n;i++) for (long long j=1;j<=m;j++) { scanf("%lld",&map[i][j]); mx=max(mx,map[i][j]); } if ((n==1) && (m==1)) { printf("0\n"); return; } col[1][1]=1; for (long long i=1;i<=n;i++) for (long long j=1;j<=m;j++) for (long long k=1;k<=4;k++) col[i+dx[k]][j+dy[k]]=col[i][j]^1; for (long long i=1;i<=n;i++) for (long long j=1;j<=m;j++) { if (col[i][j]) {n1++;s1+=map[i][j];} else {n2++;s2+=map[i][j];} } if (n1!=n2) work1(); else work2();}int main(){ scanf("%lld",&tt); for (long long i=1;i<=tt;i++) work(); return 0;}
BZOJ 2756 奇怪的游戏
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。