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

 const inf=;
type node=record
po,flow,next:longint;
end; var e,w:array[..] of node;
num:array[..,..] of longint;
cur,pre,p,st,q,numh,s,h,d:array[..] of longint;
can,v:array[..] of boolean;
n,m,i,j,x,y,len,k,t,f:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure add(x,y:longint);
begin
inc(len);
w[len].po:=y;
inc(d[y]);
w[len].next:=q[x];
q[x]:=len;
end; procedure ins(x,y,f:longint);
begin
inc(len);
e[len].po:=y;
e[len].flow:=f;
e[len].next:=p[x];
p[x]:=len;
end; procedure build(x,y,f:longint);
begin
ins(x,y,f);
ins(y,x,);
end; procedure dfs(x:longint);
var i,y:longint;
begin
v[x]:=true;
can[x]:=false;
i:=q[x];
while i<> do
begin
y:=w[i].po;
if not v[y] then dfs(y);
i:=w[i].next;
end;
end; function sap:longint;
var i,j,u,tmp,neck,q:longint;
begin
u:=;
sap:=;
for i:= to t do
cur[i]:=p[i];
numh[]:=t+;
neck:=inf;
while h[]<t+ do
begin
i:=cur[u];
d[u]:=neck;
while i<>- do
begin
j:=e[i].po;
if (e[i].flow>) and (h[u]=h[j]+) then
begin
neck:=min(neck,e[i].flow);
cur[u]:=i;
pre[j]:=u;
u:=j;
if u=t then
begin
sap:=sap+neck;
while u<> do
begin
u:=pre[u];
j:=cur[u];
dec(e[j].flow,neck);
inc(e[j xor ].flow,neck);
end;
neck:=inf;
end;
break;
end;
i:=e[i].next;
end;
if i=- then
begin
dec(numh[h[u]]);
if numh[h[u]]= then exit;
q:=-;
tmp:=t;
i:=p[u];
while i<>- do
begin
j:=e[i].po;
if e[i].flow> then
if h[j]<tmp then
begin
q:=i;
tmp:=h[j];
end;
i:=e[i].next;
end;
h[u]:=tmp+;
inc(numh[h[u]]);
cur[u]:=q;
if u<> then
begin
u:=pre[u];
neck:=d[u];
end;
end;
end;
end; begin
readln(n,m);
for i:= to n- do
for j:= to m- do
begin
inc(k);
num[i,j]:=k;
end; for i:= to n*m do
begin
read(s[i],k);
for j:= to k do
begin
read(x,y);
add(i,num[x,y]);
end;
end;
for i:= to n do
for j:=m- downto do
add(num[i,j],num[i,j-]); f:=; t:=;
for i:= to n*m do
if d[i]= then
begin
inc(t);
st[t]:=i;
end; while f<=t do
begin
x:=st[f];
can[x]:=true;
i:=q[x];
while i<> do
begin
y:=w[i].po;
dec(d[y]);
if d[y]= then
begin
inc(t);
st[t]:=y;
end;
i:=w[i].next;
end;
inc(f);
end;
for i:= to n*m do
if not can[i] then
begin
fillchar(v,sizeof(v),false);
dfs(i);
end;
t:=n*m+; k:=; len:=-;
fillchar(p,sizeof(p),);
for i:= to n*m do
if can[i] then
begin
if s[i]> then
begin
build(,i,s[i]);
k:=k+s[i];
end
else build(i,t,-s[i]);
j:=q[i];
while j<> do
begin
y:=w[j].po;
if can[y] then build(y,i,inf);
j:=w[j].next;
end;
end;
writeln(k-sap);
end.
05-08 15:34