打猎

版权声明:本文为博主原创文章,未经博主允许不得转载。(除非给钱。。。/贪婪) https://blog.csdn.net/SSL_zeng_yu/article/details/78904615
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.




猜你喜欢

转载自blog.csdn.net/SSL_zeng_yu/article/details/78904615
今日推荐