题做多的话不难想到可能是以行列作为二分图两个点集,然后网络流相关
具体怎么弄呢
我们可以用求补集的思想,假设有解
我们先把棋盘能放的地方放满士兵,然后我们尽量的把士兵拿走
并且要满足行和列的要求,
说到这方法就很明显了
ans=n*m-障碍数-最大流
我们用x[i]表示棋盘放满后第i行最多能移开的士兵数
y[i]表示棋盘放满后第i列最多能移开的士兵数
然后建图就更明显了,不多说
无解预先判断一下即可
1 const inf=10000007; 2 type node=record 3 next,point,flow:longint; 4 end; 5 6 var edge:array[0..50010] of node; 7 he,li,cur,p,numh,pre,h,d:array[0..300] of longint; 8 a:array[0..110,0..110] of boolean; 9 k,i,j,n,m,x,y,len,t:longint; 10 11 function min(a,b:longint):longint; 12 begin 13 if a>b then exit(b) else exit(a); 14 end; 15 16 procedure add(x,y,f:longint); 17 begin 18 inc(len); 19 edge[len].point:=y; 20 edge[len].flow:=f; 21 edge[len].next:=p[x]; 22 p[x]:=len; 23 end; 24 25 function sap:longint; 26 var u,i,j,neck,tmp,q:longint; 27 begin 28 neck:=inf; 29 u:=0; 30 numh[0]:=t+1; 31 h[0]:=0; 32 sap:=0; 33 for i:=0 to t do 34 cur[i]:=p[i]; 35 while h[0]-1 do 40 begin 41 j:=edge[i].point; 42 if (edge[i].flow>0) and (h[u]=h[j]+1) then 43 begin 44 neck:=min(neck,edge[i].flow); 45 pre[j]:=u; 46 cur[u]:=i; 47 u:=j; 48 if u=t then 49 begin 50 sap:=sap+neck; 51 while u<>0 do 52 begin 53 u:=pre[u]; 54 j:=cur[u]; 55 dec(edge[j].flow,neck); 56 inc(edge[j xor 1].flow,neck); 57 end; 58 neck:=inf; 59 end; 60 break; 61 end; 62 i:=edge[i].next; 63 end; 64 if i=-1 then 65 begin 66 dec(numh[h[u]]); 67 if numh[h[u]]=0 then exit; 68 tmp:=t; 69 i:=p[u]; 70 q:=-1; 71 while i<>-1 do 72 begin 73 j:=edge[i].point; 74 if edge[i].flow>0 then 75 if h[j] 0 then 86 begin 87 u:=pre[u]; 88 neck:=d[u]; 89 end; 90 end; 91 end; 92 end; 93 94 begin 95 len:=-1; 96 fillchar(p,sizeof(p),255); 97 readln(n,m,k); 98 t:=n+m+1; 99 for i:=1 to n do100 read(he[i]);101 for i:=1 to m do102 read(li[i]);103 for i:=1 to k do104 begin105 readln(x,y);106 a[x,y]:=true;107 inc(he[x]);108 inc(li[y]);109 end;110 for i:=1 to n do111 begin112 if he[i]>m then113 begin114 writeln('JIONG!');115 halt;116 end;117 add(0,i,m-he[i]);118 add(i,0,0);119 end;120 for i:=1 to m do121 begin122 if li[i]>n then123 begin124 writeln('JIONG!');125 halt;126 end;127 add(i+n,t,n-li[i]);128 add(t,i+n,0);129 end;130 for i:=1 to n do131 for j:=1 to m do132 if not a[i,j] then133 begin134 add(i,j+n,1);135 add(j+n,i,0);136 end;137 writeln(n*m-k-sap);138 end.