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

    对棋盘黑白染色后,若n和m都是奇数(即白色和黑色点数不同),可以直接算得答案(根据白-黑不变);若n和m不都是奇数,二分答案(二分的上限要大一点,开$2^50$),最后都要用用网络流来判定。
    考虑判定,将白色点放在左边,黑色点放在右边,源点流向白点的流量是白点与答案的差,黑点流向汇点的流量是黑点与答案的差,白点向每一个相邻的黑点流inf的边,判断是否满流即可。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 2005
      4 #define ll long long
      5 #define inf (1LL<<50)
      6 struct ji{
      7     int nex,to;
      8     ll len;
      9 }edge[N*5];
     10 queue<int>q;
     11 int E,T,t,n,m,a[51][51],id[51][51],head[N],work[N],d[N];
     12 ll l,r,s1,s2,mid;
     13 void add(int x,int y,ll z){
     14     edge[E].nex=head[x];
     15     edge[E].to=y;
     16     edge[E].len=z;
     17     head[x]=E++;
     18     if (E&1)add(y,x,0);
     19 }
     20 bool bfs(){
     21     q.push(0);
     22     memset(d,-1,sizeof(d));
     23     d[0]=0;
     24     while (!q.empty()){
     25         int k=q.front();
     26         q.pop();
     27         for(int i=head[k];i!=-1;i=edge[i].nex)
     28             if ((edge[i].len)&&(d[edge[i].to]<0)){
     29                 d[edge[i].to]=d[k]+1;
     30                 q.push(edge[i].to);
     31             }
     32     }
     33     return d[T]>=0;
     34 }
     35 ll dfs(int k,ll s){
     36     if (k==T)return s;
     37     ll p;
     38     for(int i=work[k];i!=-1;i=edge[i].nex)
     39         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
     40             p=dfs(edge[i].to,min(s,edge[i].len));
     41             if (p){
     42                 edge[i].len-=p;
     43                 edge[i^1].len+=p;
     44                 work[k]=i;
     45                 return p;
     46             }
     47         }
     48     work[k]=-1;
     49     return 0;
     50 }
     51 ll dinic(){
     52     ll k,ans=0; 
     53     while (bfs()){
     54         memcpy(work,head,sizeof(head));
     55         while (k=dfs(0,inf))ans+=k;
     56     }
     57     return ans;
     58 }
     59 bool pd(ll k){
     60     memset(head,-1,sizeof(head));
     61     E=0;
     62     for(int i=1;i<=n;i++)
     63         for(int j=1;j<=m;j++)
     64             if ((i+j)&1){
     65                 add(0,id[i][j],k-a[i][j]);
     66                 if (i>1)add(id[i][j],id[i-1][j],inf);
     67                 if (j>1)add(id[i][j],id[i][j-1],inf);
     68                 if (i<n)add(id[i][j],id[i+1][j],inf);
     69                 if (j<m)add(id[i][j],id[i][j+1],inf);
     70             }
     71             else add(id[i][j],T,k-a[i][j]);
     72     return dinic()==k*(n*m/2)-s1;
     73 }
     74 int main(){
     75     scanf("%d",&t);
     76     while (t--){
     77         scanf("%d%d",&n,&m);
     78         for(int i=1;i<=n;i++)
     79             for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
     80         for(int i=1;i<=n;i++)
     81             for(int j=1;j<=m;j++)id[i][j]=(i-1)*m+j;
     82         T=id[n][m]+1;
     83         s1=s2=l=0;
     84         for(int i=1;i<=n;i++)
     85             for(int j=1;j<=m;j++){
     86                 l=max(l,1LL*a[i][j]);
     87                 if ((i+j)&1)s1+=a[i][j];
     88                 else s2+=a[i][j];
     89             }
     90         if ((n&1)&&(m&1)){
     91             if ((s2-s1<l)||(!pd(s2-s1)))printf("-1
    ");
     92             else printf("%lld
    ",(s2-s1)*(n*m/2)-s1);
     93             continue;
     94         }
     95         if (s1!=s2){
     96             printf("-1
    ");
     97             continue;
     98         }
     99         r=inf;
    100         while (l<r){
    101             mid=(l+r>>1);
    102             if (pd(mid))r=mid;
    103             else l=mid+1;
    104         }
    105         if (!pd(l))printf("-1
    ");
    106         else printf("%lld
    ",l*n*m/2-s1);
    107     }
    108 }
    View Code
  • 相关阅读:
    [算法分析]计数排序
    [置顶] 基于stm32f103zet6之UC/OS_II的学习1(初步移植OS点灯大法)
    IOS开发(59)之Block Object的调用
    【译】测试员,敢问路在何方?来自微软工程师
    各种字符串hash
    hdu 2579 BFS
    qq相册
    程序人生之我们的故事:十年如歌(9)
    关联模型和无限极分类
    十大技巧破解电话面试
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11834236.html
Copyright © 2011-2022 走看看