zoukankan      html  css  js  c++  java
  • bzoj1565

    很明显是最大权闭合子图,但要注意
    互相保护的植物打不掉,被互相保护的植物所直接或间接保护的植物也打不掉
    我们先拓扑排序然后dfs出能打掉的点,然后做最大权闭合子图

      1 const inf=1000000007;
      2 type node=record
      3        po,flow,next:longint;
      4      end;
      5 
      6 var e,w:array[0..800010] of node;
      7     num:array[0..21,0..32] of longint;
      8     cur,pre,p,st,q,numh,s,h,d:array[0..700] of longint;
      9     can,v:array[0..700] of boolean;
     10     n,m,i,j,x,y,len,k,t,f:longint;
     11 
     12 function min(a,b:longint):longint;
     13   begin
     14     if a>b then exit(b) else exit(a);
     15   end;
     16 
     17 procedure add(x,y:longint);
     18   begin
     19     inc(len);
     20     w[len].po:=y;
     21     inc(d[y]);
     22     w[len].next:=q[x];
     23     q[x]:=len;
     24   end;
     25 
     26 procedure ins(x,y,f:longint);
     27   begin
     28     inc(len);
     29     e[len].po:=y;
     30     e[len].flow:=f;
     31     e[len].next:=p[x];
     32     p[x]:=len;
     33   end;
     34 
     35 procedure build(x,y,f:longint);
     36   begin
     37     ins(x,y,f);
     38     ins(y,x,0);
     39   end;
     40 
     41 procedure dfs(x:longint);
     42   var i,y:longint;
     43   begin
     44     v[x]:=true;
     45     can[x]:=false;
     46     i:=q[x];
     47     while i<>0 do
     48     begin
     49       y:=w[i].po;
     50       if not v[y] then dfs(y);
     51       i:=w[i].next;
     52     end;
     53   end;
     54 
     55 function sap:longint;
     56   var i,j,u,tmp,neck,q:longint;
     57   begin
     58     u:=0;
     59     sap:=0;
     60     for i:=0 to t do
     61       cur[i]:=p[i];
     62     numh[0]:=t+1;
     63     neck:=inf;
     64     while h[0]<t+1 do
     65     begin
     66       i:=cur[u];
     67       d[u]:=neck;
     68       while i<>-1 do
     69       begin
     70         j:=e[i].po;
     71         if (e[i].flow>0) and (h[u]=h[j]+1) then
     72         begin
     73           neck:=min(neck,e[i].flow);
     74           cur[u]:=i;
     75           pre[j]:=u;
     76           u:=j;
     77           if u=t then
     78           begin
     79             sap:=sap+neck;
     80             while u<>0 do
     81             begin
     82               u:=pre[u];
     83               j:=cur[u];
     84               dec(e[j].flow,neck);
     85               inc(e[j xor 1].flow,neck);
     86             end;
     87             neck:=inf;
     88           end;
     89           break;
     90         end;
     91         i:=e[i].next;
     92       end;
     93       if i=-1 then
     94       begin
     95         dec(numh[h[u]]);
     96         if numh[h[u]]=0 then exit;
     97         q:=-1;
     98         tmp:=t;
     99         i:=p[u];
    100         while i<>-1 do
    101         begin
    102           j:=e[i].po;
    103           if e[i].flow>0 then
    104             if h[j]<tmp then
    105             begin
    106               q:=i;
    107               tmp:=h[j];
    108             end;
    109           i:=e[i].next;
    110         end;
    111         h[u]:=tmp+1;
    112         inc(numh[h[u]]);
    113         cur[u]:=q;
    114         if u<>0 then
    115         begin
    116           u:=pre[u];
    117           neck:=d[u];
    118         end;
    119       end;
    120     end;
    121   end;
    122 
    123 begin
    124   readln(n,m);
    125   for i:=0 to n-1 do
    126     for j:=0 to m-1 do
    127     begin
    128       inc(k);
    129       num[i,j]:=k;
    130     end;
    131 
    132   for i:=1 to n*m do
    133   begin
    134     read(s[i],k);
    135     for j:=1 to k do
    136     begin
    137       read(x,y);
    138       add(i,num[x,y]);
    139     end;
    140   end;
    141   for i:=0 to n do
    142     for j:=m-1 downto 1 do
    143       add(num[i,j],num[i,j-1]);
    144 
    145   f:=1; t:=0;
    146   for i:=1 to n*m do
    147     if d[i]=0 then
    148     begin
    149       inc(t);
    150       st[t]:=i;
    151     end;
    152 
    153   while f<=t do
    154   begin
    155     x:=st[f];
    156     can[x]:=true;
    157     i:=q[x];
    158     while i<>0 do
    159     begin
    160       y:=w[i].po;
    161       dec(d[y]);
    162       if d[y]=0 then
    163       begin
    164         inc(t);
    165         st[t]:=y;
    166       end;
    167       i:=w[i].next;
    168     end;
    169     inc(f);
    170   end;
    171   for i:=1 to n*m do
    172     if not can[i] then
    173     begin
    174       fillchar(v,sizeof(v),false);
    175       dfs(i);
    176     end;
    177   t:=n*m+1; k:=0; len:=-1;
    178   fillchar(p,sizeof(p),255);
    179   for i:=1 to n*m do
    180     if can[i] then
    181     begin
    182       if s[i]>0 then
    183       begin
    184         build(0,i,s[i]);
    185         k:=k+s[i];
    186       end
    187       else build(i,t,-s[i]);
    188       j:=q[i];
    189       while j<>0 do
    190       begin
    191         y:=w[j].po;
    192         if can[y] then build(y,i,inf);
    193         j:=w[j].next;
    194       end;
    195     end;
    196   writeln(k-sap);
    197 end.
    View Code
  • 相关阅读:
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    linux中的cd ..和cd -命令有什么区别?
    GCC使用
  • 原文地址:https://www.cnblogs.com/phile/p/4472939.html
Copyright © 2011-2022 走看看