• bzoj2756


    看到相邻格子都+1的操作一下就想到黑白染色了
    相邻格子都+1说明不管怎么弄,黑格子的总和和白格子总和的差总是定值
    这里首先要注意,最后不一定变成的是所有元素中的最大值,可能比它大
    比如 1 2 2 
         2 1 0  这里最后可以全变成3
    所以做题的时候下结论一定要小心,我们不妨设最后都变成了x,c1,c2表示黑白格子个数,s1,s2分别表示原来黑白格子元素和
    则x*c1-s1=x*c2-s2
    则(c1-c2)*x=s1-s2
    如果棋盘格子数为奇数,则,最后一定变成(s1-s2)/(c1-c2),我们只要验证这个即可
    否则,当s1≠s2则无解
    等于的话就有许多解,随着x的增大显然操作次数增多,所以我们二分x判定
    如何判定呢?
    我们将s连黑点,白点连t,流量是x-初始值
    对相邻黑白点连inf的边,表示这两个格子可以共同+1
    最后我们只要判断是否满流即可

      1 const inf=int64(1) shl 36;
      2       dx:array[1..4] of longint=(0,0,-1,1);
      3       dy:array[1..4] of longint=(1,-1,0,0);
      4 
      5 type node=record
      6        next,po:longint;
      7        flow:int64;
      8      end;
      9 
     10 var e:array[0..400010] of node;
     11     p,cur,pre,numh,h:array[0..1640] of longint;
     12     d:array[0..1640] of int64;
     13     num:array[0..40,0..40] of longint;
     14     a:array[0..40,0..40] of int64;
     15     test,t,i,n,m,j,k,len:longint;
     16     ans,mx,s1,s2,l,r,mid:int64;
     17 
     18 function min(a,b:int64):int64;
     19   begin
     20     if a>b then exit(b) else exit(a);
     21   end;
     22 
     23 procedure add(x,y:longint;f:int64);
     24   begin
     25     inc(len);
     26     e[len].po:=y;
     27     e[len].flow:=f;
     28     e[len].next:=p[x];
     29     p[x]:=len;
     30   end;
     31 
     32 procedure build(x,y:longint;f:int64);
     33   begin
     34     add(x,y,f);
     35     add(y,x,0);
     36   end;
     37 
     38 function sap:int64;
     39   var u,i,j,tmp,q:longint;
     40       neck:int64;
     41 
     42   begin
     43     fillchar(h,sizeof(h),0);
     44     fillchar(numh,sizeof(numh),0);
     45     for i:=0 to t do
     46       cur[i]:=p[i];
     47     neck:=inf;
     48     numh[0]:=t+1;
     49     u:=0;
     50     sap:=0;
     51     while h[0]<t+1 do
     52     begin
     53       d[u]:=neck;
     54       i:=cur[u];
     55       while i<>-1 do
     56       begin
     57         j:=e[i].po;
     58         if (e[i].flow>0) and (h[u]=h[j]+1) then
     59         begin
     60           neck:=min(neck,e[i].flow);
     61           cur[u]:=i;
     62           pre[j]:=u;
     63           u:=j;
     64           if u=t then
     65           begin
     66             sap:=sap+neck;
     67             while u<>0 do
     68             begin
     69               u:=pre[u];
     70               j:=cur[u];
     71               dec(e[j].flow,neck);
     72               inc(e[j xor 1].flow,neck);
     73             end;
     74             neck:=inf;
     75           end;
     76           break;
     77         end;
     78         i:=e[i].next;
     79       end;
     80       if i=-1 then
     81       begin
     82         dec(numh[h[u]]);
     83         if numh[h[u]]=0 then exit;
     84         q:=-1;
     85         tmp:=t;
     86         i:=p[u];
     87         while i<>-1 do
     88         begin
     89           j:=e[i].po;
     90           if (e[i].flow>0) and (h[j]<tmp) then
     91           begin
     92             tmp:=h[j];
     93             q:=i;
     94           end;
     95           i:=e[i].next;
     96         end;
     97         cur[u]:=q;
     98         h[u]:=tmp+1;
     99         inc(numh[h[u]]);
    100         if u<>0 then
    101         begin
    102           u:=pre[u];
    103           neck:=d[u];
    104         end;
    105       end;
    106     end;
    107   end;
    108 
    109 function check(w:int64):boolean;
    110   var i,j,x,y:longint;
    111       s:int64;
    112   begin
    113     len:=-1;
    114     s:=0;
    115     fillchar(p,sizeof(p),255);
    116     for i:=1 to n do
    117       for j:=1 to m do
    118         if (i+j) mod 2=1 then build(num[i,j],t,w-a[i,j])
    119         else begin
    120           build(0,num[i,j],w-a[i,j]);
    121           for k:=1 to 4 do
    122           begin
    123             x:=i+dx[k];
    124             y:=j+dy[k];
    125             if num[x,y]>0 then build(num[i,j],num[x,y],inf);
    126           end;
    127           s:=s+w-a[i,j];
    128         end;
    129 
    130     if sap<>s then exit(false)
    131     else begin
    132       ans:=s;
    133       exit(true);
    134     end;
    135   end;
    136 
    137 begin
    138   readln(test);
    139   while test>0 do
    140   begin
    141     dec(test);
    142     readln(n,m);
    143     fillchar(num,sizeof(num),0);
    144     s1:=0;
    145     s2:=0;
    146     k:=0;
    147     mx:=0;
    148     for i:=1 to n do
    149       for j:=1 to m do
    150       begin
    151         read(a[i,j]);
    152         inc(k);
    153         num[i,j]:=k;
    154         if (i+j) mod 2=0 then s1:=s1+a[i,j]
    155         else s2:=s2+a[i,j];
    156         if a[i,j]>mx then mx:=a[i,j];
    157       end;
    158     t:=n*m+1;
    159     ans:=-1;
    160     if n*m mod 2=1 then
    161     begin
    162       if (mx<=s1-s2) and check(s1-s2) then writeln(ans)
    163       else writeln(-1);
    164     end
    165     else begin
    166       if s1<>s2 then writeln(-1)
    167       else begin
    168         l:=mx;
    169         r:=int64(1) shl 33;
    170         while l<=r do
    171         begin
    172           mid:=(l+r) shr 1;
    173           if check(mid) then r:=mid-1
    174           else l:=mid+1;
    175         end;
    176         writeln(ans);
    177       end;
    178     end;
    179   end;
    180 end.
    181 
    182  
    View Code
  • 相关阅读:
    Mybatis入门
    java开发七大原则
    常用的一些实用类
    sql语句大全
    jsp中9个隐含对象
    解决POST和GET方式的中文乱码问题
    Servlet跳转页面的重定向和转发
    通用增删改查的方式
    IDEA 部署spring Cloud
    Oracle基础语法
  • 原文地址:https://www.cnblogs.com/phile/p/4472969.html
Copyright © 2020-2023  润新知