• bzoj1976


    终于忙完期末考试了,即将进入愉快的暑假(虽然暑假作业奇多,但好歹终于能有大量时间刷题了)

    先把上次新一类最小割留下的一道题目A了复习一下;

    题目看起来很复杂,实际上和bzoj2132是同一个类型的

    用S集合表示放正能量,T集合表示放负能量(可自行参照上一篇文章)

    只是有几个不同点:

    1. 有些点是已经确定为S或T集合中的点

    2. 选择点属于S或者属于T都是没有收益的

    对于未知的问题我们要转化为已知的问题来求解

    首先我们来处理2,考虑到割是我们所得不到的收益,

    于是我们可以把每个点选择属于S或者属于T产生的收益都当做是个1,

    也就是对于每个点i,连接s--->i, i--->t 容量为1;

    最后ans=n*n*n(抵消我们之前强加的收益)+图中的边数-mincut;

    下面就是1没有解决了,考虑到割是我们所得不到的收益,

    所以,对于那些已经确定为S集合中的点(T集合同理),我们只要使

    s--->i 容量为inf,也就让这条边一定不成为割边,那么就满足了这个点的确定性;

    好了,即使是立体的,依然可以黑白染色划分二分图,所以其余实现细节类似bzoj2132,这里不加赘述。

      1 const inf=100000007;
      2       dx:array[1..6] of integer=(-1,1,0,0,0,0);
      3       dy:array[1..6] of integer=(0,0,-1,1,0,0);
      4       dz:array[1..6] of integer=(0,0,0,0,-1,1);
      5 type node=record
      6        next,flow,point:longint;
      7      end;
      8 
      9 var edge:array[0..2000010] of node;
     10     h,numh,p,cur,d,pre:array[0..64010] of longint;
     11     num:array[0..41,0..41,0..41] of longint;
     12     t,len,i,j,n,k,x,y,z,m,ans,sum:longint;
     13     s:ansistring;
     14 
     15 function min(a,b:longint):longint;
     16   begin
     17     if a>b then exit(b) else exit(a);
     18   end;
     19 
     20 procedure add(x,y,f:longint);
     21   begin
     22     inc(len);
     23     edge[len].point:=y;
     24     edge[len].flow:=f;
     25     edge[len].next:=p[x];
     26     p[x]:=len;
     27   end;
     28 
     29 function sap:longint;
     30   var u,i,j,q,neck,tmp:longint;
     31   begin
     32     numh[0]:=t+1;
     33     for i:=0 to t do
     34       cur[i]:=p[i];
     35     u:=0;
     36     sap:=0;
     37     neck:=inf;
     38     while h[0]<t+1 do
     39     begin
     40       d[u]:=neck;
     41       i:=cur[u];
     42       while i<>-1 do
     43       begin
     44         j:=edge[i].point;
     45         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     46         begin
     47           cur[u]:=i;
     48           pre[j]:=u;
     49           neck:=min(neck,edge[i].flow);
     50           u:=j;
     51           if u=t then
     52           begin
     53             while u<>0 do
     54             begin
     55               u:=pre[u];
     56               i:=cur[u];
     57               dec(edge[i].flow,neck);
     58               inc(edge[i xor 1].flow,neck);
     59             end;
     60             sap:=sap+neck;
     61           end;
     62           break;
     63         end;
     64         i:=edge[i].next;
     65       end;
     66       if i=-1 then
     67       begin
     68         dec(numh[h[u]]);
     69         if numh[h[u]]=0 then exit;
     70         tmp:=t;
     71         i:=p[u];
     72         q:=-1;
     73         while i<>-1 do
     74         begin
     75           j:=edge[i].point;
     76           if (edge[i].flow>0) and (h[j]<tmp) then
     77           begin
     78             q:=i;
     79             tmp:=h[j];
     80           end;
     81           i:=edge[i].next;
     82         end;
     83         h[u]:=tmp+1;
     84         inc(numh[h[u]]);
     85         cur[u]:=q;
     86         if u<>0 then
     87         begin
     88           u:=pre[u];
     89           neck:=d[u];
     90         end;
     91       end;
     92     end;
     93   end;
     94 
     95 begin
     96   len:=-1;
     97   fillchar(p,sizeof(p),255);
     98   readln(n);
     99   t:=n*n*n+1;
    100   for i:=1 to n do
    101   begin
    102     for j:=1 to n do
    103     begin
    104       readln(s);
    105       for k:=1 to n do
    106       begin
    107         inc(m);
    108         num[i,j,k]:=m;
    109         if (s[k]='N') and ((i+j+k) mod 2=1) or (s[k]='P') and ((i+j+k) mod 2=0) then
    110         begin
    111           add(0,m,inf);
    112           add(m,0,0);
    113           add(m,t,1);
    114           add(t,m,0);
    115         end
    116         else if (s[k]='N') and ((i+j+k) mod 2=0) or (s[k]='P') and ((i+j+k) mod 2=1) then
    117         begin
    118           add(m,t,inf);
    119           add(t,m,0);
    120           add(0,m,1);
    121           add(m,0,0);
    122         end
    123         else if s[k]='?' then
    124         begin
    125           add(0,m,1);
    126           add(m,0,0);
    127           add(m,t,1);
    128           add(t,m,0);
    129         end;
    130       end;
    131     end;
    132     if i<>n then readln;
    133   end;
    134   for i:=1 to n do
    135     for j:=1 to n do
    136       for k:=1 to n do
    137         for m:=1 to 6 do
    138         begin
    139           x:=i+dx[m];
    140           y:=j+dy[m];
    141           z:=k+dz[m];
    142           if num[x,y,z]>0 then
    143           begin
    144             add(num[i,j,k],num[x,y,z],1);
    145             add(num[x,y,z],num[i,j,k],0);
    146             inc(sum);
    147           end;
    148         end;
    149   sum:=sum div 2+n*n*n;
    150   writeln(sum-sap);
    151 end.
    View Code
  • 相关阅读:
    自定义类似smarty模板
    PHP函数相关知识点
    cookie的使用和设置
    进程通过内核缓存区请求设备I/O的一些事情
    多线程模型和问题
    C10K问题和多进程模型
    node.js----一个httpserver提交和解析get参数的例子
    nodejs解析url参数的三种方法
    node.js http模块和fs模块上机实验·
    c++中的srand()和rand() 转载 自:http://blog.sina.com.cn/s/blog_624c2c4001012f67.html
  • 原文地址:https://www.cnblogs.com/phile/p/4473225.html
Copyright © 2020-2023  润新知