很明显是最大权闭合子图,但要注意
互相保护的植物打不掉,被互相保护的植物所直接或间接保护的植物也打不掉
我们先拓扑排序然后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.