• bzoj3144


    最小割解决最优值最突出的特点就是要将对象划分到两个集合中
    这题很明显,裸的最小割
    先把点连成一根根柱子,就是p(x,y,k)-->p(x,y,k+1)流量是P(x,y,k+1)的不和谐值
    然后s与p(x,y,1)连边,流量是p(x,y,1)的不和谐值
    最后再将p(x,y,r)都连向t
    下面就是解决切割限制了,其实很简单,就是我们通过连边是不满足限制的点不构成一个割的方案
    具体来说就是,对于任意p(x,y,k) (k<r) 连p(x',y',k+d)--->p(x,y,k) 流量inf,x',y'为邻居
    画图可知正确性

      1 const inf=200000007;
      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        flow,next,point:longint;
      7      end;
      8 
      9 var edge:array[0..3000010] of node;
     10     pre,p,cur,numh,h,d:array[0..64010] of longint;
     11     num:array[0..40,0..40,0..40] of longint;
     12     l,w,n,m,r,k,j,t,len,x,y,i:longint;
     13 
     14 function min(a,b:longint):longint;
     15   begin
     16     if a>b then exit(b) else exit(a);
     17   end;
     18 
     19 procedure add(x,y,f:longint);
     20   begin
     21     inc(len);
     22     edge[len].point:=y;
     23     edge[len].flow:=f;
     24     edge[len].next:=p[x];
     25     p[x]:=len;
     26   end;
     27 
     28 procedure build(x,y,f:longint);
     29   begin
     30     add(x,y,f);
     31     add(y,x,0);
     32   end;
     33 
     34 function sap:longint;
     35   var tmp,u,i,j,q,neck:longint;
     36   begin
     37     for i:=0 to t do
     38       cur[i]:=p[i];
     39     numh[0]:=t+1;
     40     neck:=inf;
     41     u:=0;
     42     sap:=0;
     43     while h[0]<t+1 do
     44     begin
     45       d[u]:=neck;
     46       i:=cur[u];
     47       while i<>-1 do
     48       begin
     49         j:=edge[i].point;
     50         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     51         begin
     52           pre[j]:=u;
     53           cur[u]:=i;
     54           neck:=min(neck,edge[i].flow);
     55           u:=j;
     56           if u=t then
     57           begin
     58             sap:=sap+neck;
     59             while u<>0 do
     60             begin
     61               u:=pre[u];
     62               j:=cur[u];
     63               dec(edge[j].flow,neck);
     64               inc(edge[j xor 1].flow,neck);
     65             end;
     66             neck:=inf;
     67           end;
     68           break;
     69         end;
     70         i:=edge[i].next;
     71       end;
     72       if i=-1 then
     73       begin
     74         dec(numh[h[u]]);
     75         if numh[h[u]]=0 then exit;
     76         q:=-1;
     77         tmp:=t;
     78         i:=p[u];
     79         while i<>-1 do
     80         begin
     81           j:=edge[i].point;
     82           if edge[i].flow>0 then
     83             if h[j]<tmp then
     84             begin
     85               q:=i;
     86               tmp:=h[j];
     87             end;
     88           i:=edge[i].next;
     89         end;
     90         h[u]:=tmp+1;
     91         inc(numh[h[u]]);
     92         cur[u]:=q;
     93         if u<>0 then
     94         begin
     95           u:=pre[u];
     96           neck:=d[u];
     97         end;
     98       end;
     99     end;
    100   end;
    101 
    102 begin
    103   len:=-1;
    104   fillchar(p,sizeof(p),255);
    105   readln(n,m,r);
    106   readln(l);
    107   t:=0;
    108   for k:=1 to r do
    109     for i:=1 to n do
    110       for j:=1 to m do
    111       begin
    112         read(x);
    113         inc(t);
    114         num[k,i,j]:=t;
    115         build(num[k-1,i,j],t,x);
    116       end;
    117   inc(t);
    118   for i:=1 to n do
    119     for j:=1 to m do
    120     begin
    121       build(num[r,i,j],t,inf);
    122       for w:=1 to 4 do
    123       begin
    124         x:=i+dx[w];
    125         y:=j+dy[w];
    126         if (x>0) and (x<=n) and (y>0) and (y<=m) then
    127         begin
    128           for k:=1 to r-l do
    129             build(num[k+l,x,y],num[k,i,j],inf);
    130         end;
    131       end;
    132     end;
    133 
    134   writeln(sap);
    135 end.
    View Code
  • 相关阅读:
    C++编程开发学习的50条建议(转)
    编程思想:我现在是这样编程的(转)
    Linux系统编程@多线程与多进程GDB调试
    字符串分割函数 STRTOK & STRTOK_R (转)
    C语言指针与数组的定义与声明易错分析
    C语言 a和&a的区别
    C语言二重指针与malloc
    【C语言入门】C语言的组成结构(基础完整篇)!
    程序员吐槽女友败家:开酒店必须400元起步,工资却不到自己的一半!
    怎样才能和编程语言对上眼?你需要做些准备以及...
  • 原文地址:https://www.cnblogs.com/phile/p/4472968.html
Copyright © 2020-2023  润新知