• bzoj 2756: [SCOI2012]奇怪的游戏


    Description

    Blinker最近喜欢上一个奇怪的游戏。
    这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻
    的格子,并使这两个数都加上 1。
    现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同
    一个数则输出-1。

    Input

    输入的第一行是一个整数T,表示输入数据有T轮游戏组成。
    每轮游戏的第一行有两个整数N和M, 分别代表棋盘的行数和列数。
    接下来有N行,每行 M个数。 

    Output


      对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出-1。

    Sample Input

    2
    2 2
    1 2
    2 3
    3 3
    1 2 3
    2 3 4
    4 3 2

    Sample Output

    2
    -1

    HINT

    【数据范围】

        对于30%的数据,保证  T<=10,1<=N,M<=8

    对于100%的数据,保证  T<=10,1<=N,M<=40,所有数为正整数且小于1000000000 

     

    Source

    一道很不错的网络流啊,一开始以为是所有数都变成最大的那个数,然后以为是个大水题,wa了之后觉得可以二分,结果又wa了;

    看了题解之后发现自己简直mdzz;

    首先看到这种题目的第一反应就是黑白染色,然后我们设黑点的数量为num1,黑点的权值和为sum1,白点的数量为num2,白点的权值和为sum2;

    那么我们假设变为的数=x,那么num1*x-sum1=num2*x-sum2,如果num1!=num2,那么x可以直接解出来,x=(sum1-sum2)/(num1-num2);

    如果num1=num2,因为每个点都能有匹配,那么答案满足可二分性,因为假如能变成x,那么对于k>=x,那么肯定也能变成k,因为可以先变成x,然后一对匹配就一直加;

    所以对于这个num1=num2二分x就可以了;

    把x求出来之后用最大流check:

    //MADE BY QT666
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define int long long
    using namespace std;
    typedef long long ll;
    const int N=100050;
    const int Inf=3e15;
    int head[N],to[N],nxt[N],s[N],q[N],cnt=1,level[N],S,T;
    ll F;
    void Addedge(int x,int y,int z) {
        to[++cnt]=y,s[cnt]=z,nxt[cnt]=head[x],head[x]=cnt;
    }
    void lnk(int x,int y,int z){
        Addedge(x,y,z),Addedge(y,x,0);
    }
    bool bfs(){
        for(int i=S;i<=T;i++) level[i]=0;
        q[0]=S,level[S]=1;int t=0,sum=1;
        while(t<sum){
    	int x=q[t++];
    	if(x==T) return 1;
    	for(int i=head[x];i;i=nxt[i]){
    	    int y=to[i];
    	    if(s[i]&&level[y]==0){
    		level[y]=level[x]+1;
    		q[sum++]=y;
    	    }
    	}
        }
        return 0;
    }
    int dfs(int x,int maxf){
        if(x==T) return maxf;
        int ret=0;
        for(int i=head[x];i;i=nxt[i]){
    	int y=to[i];int f=s[i];
    	if(level[y]==level[x]+1&&f){
    	    int minn=min(f,maxf-ret);
    	    f=dfs(y,minn);
    	    s[i]-=f,s[i^1]+=f,ret+=f;
    	    if(ret==maxf) break;
    	}
        }
        if(!ret) level[x]=0;
        return ret;
    }
    void Dinic(){
        F=0;while(bfs()) F+=dfs(S,Inf);
    }
    bool check(){
        for(int i=head[S];i;i=nxt[i]) if(s[i]) return 0;
        for(int i=head[T];i;i=nxt[i]) if(s[i^1]) return 0;
        return 1;
    }
    int a[100][100],maxn,xh[100][100];
    int mx[]={1,-1,0,0},my[]={0,0,1,-1},n,m,tt,tot;
    bool judge(int mid){
        memset(head,0,sizeof(head));cnt=1;
        for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    	    if((i+j)%2==0){
    		lnk(S,xh[i][j],mid-a[i][j]);
    		for(int k=0;k<4;k++){
    		    int x=i+mx[k],y=j+my[k];
    		    if(x>=1&&x<=n&&y>=1&&y<=m) lnk(xh[i][j],xh[x][y]+tt,Inf);
    		}
    	    }
    	    else lnk(xh[i][j]+tt,T,mid-a[i][j]);
    	}
        }
        Dinic();return check();
    }
    main(){
        int t;scanf("%lld",&t);
        while(t--){
    	scanf("%lld%lld",&n,&m);maxn=0;
    	for(int i=1;i<=n;i++){
    	    for(int j=1;j<=m;j++){
    		scanf("%lld",&a[i][j]);maxn=max(maxn,a[i][j]);
    	    }
    	}
    	tt=0,tot=0;int sum1=0,sum2=0;
    	for(int i=1;i<=n;i++){
    	    for(int j=1;j<=m;j++){
    		if((i+j)%2==0) xh[i][j]=++tt,sum1+=a[i][j];
    		else xh[i][j]=++tot,sum2+=a[i][j];
    	    }
    	}
    	T=tt+tot+1;
    	if(tt!=tot){
    	    int mid=(sum1-sum2)/(tt-tot);
    	    if(judge(mid)) cout<<F<<endl;
    	    else puts("-1");
    	}
    	if(tt==tot){
    	    int l=maxn,r=2e9,ans=-1;
    	    while(l<=r){
    		int mid=(l+r)>>1;
    		if(judge(mid)) ans=F,r=mid-1;
    		else l=mid+1;
    	    }
    	    cout<<ans<<endl;
    	}
        }
        return 0;
    }
    
  • 相关阅读:
    [转].net自定义验证控件CustomValidator的使用
    After Effects CS4入门经典—高手之路
    [转]用JS获取地址栏参数的方法(超级简单)
    SpringBoot中通过SpringBootServletInitializer如何实现容器初始化
    SpringBoot之二:部署Spring Boot应用程序方式
    Zookeeper学习(八):Zookeeper的数据发布与订阅模式
    Dubbo各种协议详解
    Annotation之四:注解中的-Xlint:unchecked和 -Xlint:deprecation
    mina在spring中的配置多个端口
    Mina2中IoService
  • 原文地址:https://www.cnblogs.com/qt666/p/7674810.html
Copyright © 2020-2023  润新知