v猎人要在n*n的格子里打鸟,他可以在某一行中打一枪,这样此行中的所有鸟都被打掉,也可以在某一列中打,这样此列中的所有鸟都打掉。问至少打几枪,才能打光所有的鸟?
v建图:二分图的X部为每一行,Y部为每一列,如果(i,j)有一只鸟,那么连接X部的i与Y部的j。
v该二分图的最大匹配数则是最少要打的枪数。
var
map:array[0..101,0..101] of boolean;
sl:string;
ch:char;
link:array[0..101] of longint;
a,b:array[1..101,1..101]of longint;
cover:array[0..101] of boolean;
kk,i,j,n,m,s,ans,x,y,n1,m1,i1,j1:longint;
function find(i:longint):boolean;
var
k,q:longint;
begin
find:=true;
for k:=1 to n do
if map[i,k] and not(cover[k])
then begin
q:=link[k];
link[k]:=i;
cover[k]:=true;
if (q=0) or find(q) then exit;
link[k]:=q;
end;
find:=false;
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do
begin
fillchar(cover,sizeof(cover),0);
find(i);
end;
end;
begin
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
read(a[i,j]);
if a[i,j]=1 then inc(n1);
b[n1,1]:=i;
b[n1,2]:=j;
end;
for i:=1 to n1 do
begin
i1:=b[i,1];
j1:=b[i,2];
for j:=1 to n do
if a[i1,j]=1 then map[i1,j]:=true;
for j:=1 to n do
if a[j,j1]=1 then map[j,j1]:=true;
end;
for i:=1 to n do
if link[i]<>0 then inc(ans);
writeln(ans);
end.
map:array[0..101,0..101] of boolean;
sl:string;
ch:char;
link:array[0..101] of longint;
a,b:array[1..101,1..101]of longint;
cover:array[0..101] of boolean;
kk,i,j,n,m,s,ans,x,y,n1,m1,i1,j1:longint;
function find(i:longint):boolean;
var
k,q:longint;
begin
find:=true;
for k:=1 to n do
if map[i,k] and not(cover[k])
then begin
q:=link[k];
link[k]:=i;
cover[k]:=true;
if (q=0) or find(q) then exit;
link[k]:=q;
end;
find:=false;
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do
begin
fillchar(cover,sizeof(cover),0);
find(i);
end;
end;
begin
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
read(a[i,j]);
if a[i,j]=1 then inc(n1);
b[n1,1]:=i;
b[n1,2]:=j;
end;
for i:=1 to n1 do
begin
i1:=b[i,1];
j1:=b[i,2];
for j:=1 to n do
if a[i1,j]=1 then map[i1,j]:=true;
for j:=1 to n do
if a[j,j1]=1 then map[j,j1]:=true;
end;
for i:=1 to n do
if link[i]<>0 then inc(ans);
writeln(ans);
end.