zoukankan      html  css  js  c++  java
  • [SCOI2012]奇怪的游戏

    题目

    话说有没有跟我一样直接猜了一个最大值不会改变这样一个二乎乎的结论之后交上去保龄的呀

    首先看到棋盘,选择相邻的格子,非常经典的黑白染色

    显然那个二乎乎的结论是错的,随便就能(hack)

    于是我们二分这个最大值

    如果当前二分出来的最大值是(mid)(i+j)为奇数,起点连(mid-a[i][j])的边,否则向终点连(mid-a[i][j])的边,相邻的格子连流量无穷的边,跑最大流看看起点连出去的边和连向终点的边是否都满流就好了

    但是这样仅限于(n imes m)为偶数的情况

    因为之后当(n imes m)为偶数的时候我们可以把整个棋盘整体加(1),因此存在单调性,于是可以二分

    但是当(n imes m)为奇数的时候我们无论如何都得空至少一个

    我们可以考虑一下最后棋盘变成了(x)

    那么就会存在

    [x imes num_{ ext{奇}}-sum_{ ext{奇}}=x imes num_{ ext{偶}}-sum_{ ext{偶}} ]

    这个其实还是来源于上面的网络流建图,就是让两边流量平衡,由于(num_{ ext{奇}}!=num_{ ext{偶}}),我们可以直接解得

    [x=frac{sum_{ ext{奇}}-sum_{ ext{偶}}}{num_{ ext{奇}}-num_{ ext{偶}}} ]

    由于我们不能再让棋盘整体加了,于是直接判断(x)是否合法就好了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int maxn=2005;
    const LL inf=5e12;
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    std::queue<int> q;
    const int dx[]={0,0,1,-1};
    const int dy[]={1,-1,0,0};
    int head[maxn],d[maxn],id[51][51],S,T,num;
    int n,m,a[51][51],pd[maxn],cur[maxn];
    struct E{int v,nxt;LL f;}e[maxn*40];
    inline void C(int x,int y,LL f) {
    	e[++num].v=y;e[num].nxt=head[x];
    	head[x]=num;e[num].f=f;
    }
    inline void add(int x,int y,LL f) {C(x,y,f),C(y,x,0);}
    inline int BFS() {
    	for(re int i=S;i<=T;i++) d[i]=0,cur[i]=head[i];
    	d[S]=1,q.push(S);
    	while(!q.empty()) {
    		int k=q.front();q.pop();
    		for(re int i=head[k];i;i=e[i].nxt)
    		if(e[i].f&&!d[e[i].v]) d[e[i].v]=d[k]+1,q.push(e[i].v);
    	}
    	return d[T];
    }
    LL dfs(int x,LL now) {
    	if(x==T||!now) return now;
    	LL flow=0,ff;
    	for(re int& i=cur[x];i;i=e[i].nxt)
    	if(d[e[i].v]==d[x]+1) {
    		ff=dfs(e[i].v,min(now,e[i].f));
    		if(ff<=0) continue;
    		now-=ff,flow+=ff,e[i].f-=ff,e[i^1].f+=ff;
    		if(!now) break;
    	}
    	return flow;
    }
    inline int check(LL mx) {
    	num=1;memset(head,0,sizeof(head));
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=m;j++) {
    			pd[id[i][j]]=num+1;
    			if((i+j)&1) add(S,id[i][j],mx-a[i][j]);
    				else add(id[i][j],T,mx-a[i][j]);
    			if(mx<a[i][j]) return 0;
    		}
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=m;j++) {
    			if(!((i+j)&1)) continue;
    			for(re int k=0;k<4;k++) {
    				int x=i+dx[k],y=j+dy[k];
    				if(x<1||y<1||x>n||y>m) continue;
    				add(id[i][j],id[x][y],inf);
    			}
    		}
    	while(BFS()) dfs(S,inf);
    	int flag=1;
    	for(re int i=1;i<=n;i++)	
    		for(re int j=1;j<=m;j++)
    			flag&=(e[pd[id[i][j]]].f==0);
    	return flag;
    }
    int main() {
    	int Test=read();
    	while(Test--) {
    		n=read(),m=read();T=0;
    		for(re int i=1;i<=n;i++)
    			for(re int j=1;j<=m;j++) a[i][j]=read();
    		for(re int i=1;i<=n;i++)
    			for(re int j=1;j<=m;j++) id[i][j]=++T;
    		++T;
    		LL s[2],tot[2];
    		tot[0]=tot[1]=s[0]=s[1]=0;
    		for(re int i=1;i<=n;i++)
    			for(re int j=1;j<=m;j++)
    				tot[(i+j)&1]++,s[(i+j)&1]+=a[i][j];
    		if((n*m)&1) {
    			LL x=(s[1]-s[0])/(tot[1]-tot[0]);
    			if(check(x)) 
    				printf("%lld
    ",x*tot[1]-s[1]);
    			else puts("-1");			
    		}
    		else {
    			LL ans=-1,l=1,r=2e9;
    			for(re int i=1;i<=n;i++)
    				for(re int j=1;j<=m;j++) l=max(l,a[i][j]);
    			while(l<=r) {
    				LL mid=l+r>>1;
    				if(check(mid)) r=mid-1,ans=mid;
    					else l=mid+1;
    			}
    			if(ans==-1) puts("-1");
    			else printf("%lld
    ",ans*tot[1]-s[1]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    leetcode 75 颜色分类 A
    leetcode525连续数组 A
    WCF无身份验证配置
    三读设计模式
    EntityFrameWork+Oracle学习笔记搭配环境(一)
    EntityFrameWork+Oracle学习笔记DBfirst(二)
    用Python解答百度测试开发算法面试题
    Python实现采集wordpress整站数据的爬虫
    吾八哥学Python(六):运算符与表达式
    吾八哥学Python(四):了解Python基础语法(下)
  • 原文地址:https://www.cnblogs.com/asuldb/p/10593755.html
Copyright © 2011-2022 走看看