• BZOJ 2756 【SCOI2012】 奇怪的游戏


    题目链接:奇怪的游戏

      一开始这道题想岔了……想到黑白染色后对总格子数按奇偶性分类讨论,然后没发现奇数个格子的可以直接解方程……

      首先可以发现每次操作是给相邻的两个格子权值加一,因此我们把棋盘黑白染色后每次操作就是给白格子和黑格子加一。因此白格子和黑格子的增加的量是相等的。设我们有(n_1)个白格子,它们的数值和是(s_1),有(n_2)个黑格子,数值和是(s_2)。再设最后每个数都变成了(x),那么有:

    [n_1x-s_1=n_2x-s_2]

      所以当(n_1 eq n_2)时就可以直接解出(x)了。然后跑遍最大流检验一下这个(x)是否合法即可。

      然后当(n_1 = n_2)时,如果(s_1 eq s_2),那么显然无解。否则的话,我们可以发现答案是可以二分的。若(x)是一个合法的答案,因为共有偶数个格子,那么行数和列数至少有一个是偶数,我们就有一种方案把每个位置上的权值都加上一,使答案变成(x+1)。所以,二分一个答案,最大流(check)即可。

      下面贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define maxn 1610
    #define maxm 10000
    #define INF (1ll<<60)
     
    using namespace std;
    typedef long long llg;
     
    int Q,n,m,a[41][41],S,T,n1,n2,_m;
    int zx[4]={0,0,1,-1},zy[4]={1,-1,0,0};
    int head[maxn],next[maxm],to[maxm],tt;
    llg s1,s2,c[maxm];
     
    int getint(){
        int w=0;bool q=0;
        char c=getchar();
        while((c>'9'||c<'0')&&c!='-') c=getchar();
        if(c=='-') c=getchar(),q=1;
        while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
        return q?-w:w;
    }
     
    void link(int x,int y){
        to[++tt]=y;next[tt]=head[x];head[x]=tt;
        to[++tt]=x;next[tt]=head[y];head[y]=tt;
    }
     
    int d[maxn],rd,ld,dep[maxn];
    bool bfs(){
        for(int i=1;i<=T;i++) dep[i]=-1;
        ld=rd=0; d[rd++]=S; dep[S]=1;
        while(ld!=rd){
            int u=d[ld++];
            for(int i=head[u],v;v=to[i],i;i=next[i])
                if(c[i] && dep[v]==-1) dep[v]=dep[u]+1,d[rd++]=v;
        }
        return dep[T]!=-1;
    }
     
    llg dfs(int u,llg now){
        if(!now) return 0;
        if(u==T) return now;
        llg low=0,res;
        for(int i=head[u],v;v=to[i],i;i=next[i])
            if(c[i] && dep[v]==dep[u]+1){
                res=dfs(v,min(now,c[i])); low+=res;
                c[i]-=res; c[i^1]+=res; now-=res;
            }
        if(!low) dep[u]=-1;
        return low;
    }
     
    bool cheadck(llg x){
        int next=2; llg ans=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++,next+=2){
                if(a[i][j]>x) return 0;
                c[next]=x-a[i][j],c[next^1]=0;
            }
        while(next<=tt) c[next]=INF,c[next^1]=0,next+=2;
        while(bfs()) ans+=dfs(S,INF);
        return ans>=1ll*x*n1-s1;
    }
     
    void lian(int u,int x,int y){
        for(int k=0,i,j;k<4;k++){
            i=x+zx[k],j=y+zy[k];
            if(i>0 && i<=n && j>0 && j<=m)
                link(u,(i-1)*m+j);
        }
    }
     
    int main(){
    	File("a");
        Q=getint();
        while(Q--){
            n=getint(); m=getint(); _m=n1=n2=0;
            S=n*m+1; T=S+1; tt=1; s1=s2=0;
            for(int i=1,now=1;i<=n;i++)
                for(int j=1;j<=m;j++,now++){
                    _m=max(_m,a[i][j]=getint());
                    if((i+j)&1) link(S,now),s1+=a[i][j],n1++;
                    else link(now,T),s2+=a[i][j],n2++;
                }
            for(int i=1,now=1;i<=n;i++)
                for(int j=1;j<=m;j++,now++)
                    if((i+j)&1) lian(now,i,j);
            if(n1!=n2){
                llg x=(s1-s2)/(n1-n2);
                if(cheadck(x)) printf("%lld
    ",n1*x-s1);
                else printf("-1
    ");
            }
            else if(s1!=s2) printf("-1
    ");
            else{
                llg l=_m,r=s1+s2,mid;
                while(l!=r){
                    mid=(l+r)>>1;
                    if(cheadck(mid)) r=mid;
                    else l=mid+1;
                }
                printf("%lld
    ",l*n1-s1);
            }
            for(int i=1;i<=T;i++) head[i]=0;
        }
        return 0;
    }
    
  • 相关阅读:
    Linux下环境变量配置方法梳理(.bash_profile和.bashrc的区别)
    Mac下安装配置Python2和Python3并相互切换使用
    精通Python自动化脚本
    idea之Git
    python面向对象之:细分类的组成成员
    new string("abc")创建了几个对象
    进程和线程的主要区别
    Leetcode 572 另一个树的子树
    Leetcode 二叉树的坡度
    Leetcode 559 N叉树的最大深度
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6384887.html
Copyright © 2020-2023  润新知