• BZOJ2756: [SCOI2012]奇怪的游戏


    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2756

    对棋盘进行黑白染色。若答案为x,有c1*x-s1==c2*x-s2得x=(s1-s2)/(c1-c2),那么若c1!=c2,检测x就可以了。若不是就二分x。

    建图:s->黑点 c=x-a[i][j] 白点->t c=x-a[i][j] 黑->白 c=inf

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define maxn 2005
    #define eps 1e-3
    #define ll long long
    #define inf (1LL<<50)
    using namespace std;
    struct data{int obj,pre;ll c;
    }e[200500];
    int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
    int head[maxn],cur[maxn],uu[maxn],n,m,t,tot,s;
    ll c1,c2,s1,s2,a[42][42];
    ll read(){
        ll x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    void insert(int x,int y,ll z){
        e[++tot].obj=y; e[tot].c=z; e[tot].pre=head[x]; head[x]=tot; 
        e[++tot].obj=x; e[tot].c=0; e[tot].pre=head[y]; head[y]=tot;
    }
    int p(int x,int y){
        return (x-1)*m+y;
    }
    bool bfs(){
        queue<int> q; q.push(0); clr(uu,-1); uu[0]=0;
        while (!q.empty()){
            int u=q.front(); q.pop();
            for (int j=head[u];j;j=e[j].pre){
                int v=e[j].obj;
                if (uu[v]==-1&&e[j].c) {
                    uu[v]=uu[u]+1; q.push(v);
                }
            }
        }
        if (uu[t]==-1) return 0;
        return 1;
    }
    ll dfs(int x,ll mx){
        if (x==t) return mx;
        ll used=0;
        for (int j=cur[x];j;j=e[j].pre){
            int v=e[j].obj;
            if (uu[v]==uu[x]+1){
                ll w=dfs(v,min(e[j].c,mx-used));
                e[j].c-=w; e[j^1].c+=w; used+=w;
                if (e[j].c) cur[x]=j;
                if (used==mx) return mx; 
            }
        }
        if (!used) uu[x]=-1;
        return used;
    }
    ll dinic(){
        ll ans=0;
        while (bfs()){
            rep(i,0,t) cur[i]=head[i];
            ans+=dfs(0,inf);
        }
        return ans;
    }
    bool jud(ll x){
        tot=1; clr(head,0); s=0; t=n*m+1;
        ll cnt=0;
        rep(i,1,n) rep(j,1,m) {
            if ((i+j)&1) {
                insert(0,p(i,j),x-a[i][j]),cnt+=x-a[i][j];
                rep(k,0,3) {
                     int x=i+dx[k],y=j+dy[k];
                    if (x<1||x>n||y<1||y>m) continue;
                    insert(p(i,j),p(x,y),inf);     
                 }
            }
            else insert(p(i,j),t,x-a[i][j]);
         }    
         if (dinic()!=cnt) return 0;
        return 1; 
    }
    int main(){
        int T=read();
        while (T--){
            ll mx=0; c1=0,c2=0,s1=0,s2=0;
            n=read(); m=read();
            rep(i,1,n) rep(j,1,m){
                a[i][j]=read(); mx=max(mx,a[i][j]);
                if ((i+j)&1) c1++,s1+=a[i][j];
                else c2++,s2+=a[i][j];
            }
            if (c1!=c2){
                ll x=(s1-s2)/(c1-c2);
                if (x>=mx) if (jud(x)) {printf("%lld
    ",x*c1-s1); continue;}
                puts("-1");
            }
            else {
                ll l=mx,r=inf;
                while (l<=r){
                    ll mid=(l+r)/2;
                    if (jud(mid)) r=mid-1;
                    else l=mid+1;
                }
                printf("%lld
    ",l*c1-s1);
            }
        }
        return 0;
    }
  • 相关阅读:
    复旦大学软件学院预推免经验贴
    寒武纪-算法研究实习生

    C++ 笔记
    Deep Layer Aggregation论文笔记
    项目:语义分割DeepLabv3-树莓派4B部署
    神经网络加速引擎对比调研
    东南大学网安学院预推免经验帖
    中科院深圳先进院夏令营经验贴
    华东师范大学软院夏令营经验贴
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5034402.html
Copyright © 2020-2023  润新知