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

 

posted on 2015-04-10 14:11  acphile  阅读(169)  评论(0编辑  收藏  举报