首先这道题很容易想到二分图相关(给的很明确了);
但是我们发现,男孩之间都互相认识,女孩之间也互相认识
这样是不能划分点集的
但是男孩之间都互相认识,女孩之间也互相认识,所以男孩和男孩,女孩和女孩之间不存在不认识关系;
如果以不认识作为边的话,这样不就能划开点集吗?
于是我们换一个思维,要找最多的男女生互相认识,不就是找最多的男女生之间不存在不认识关系吗
所以,我们在不认识之间的男女之间连边,然后对这个二分图求最大独立集即可
最大独立集=点集x+点集y-最大匹配数(最小点覆盖)
要注意思维的转化
1 type node=record 2 point,next:longint; 3 end; 4 var edge:array[0..200010] of node; 5 p,cx,cy:array[0..500] of longint; 6 v:array[0..500] of boolean; 7 a:array[0..500,0..500] of boolean; 8 t,len,ans,g,b,m,i,j,x,y:longint; 9 10 procedure add(x,y:longint); 11 begin 12 inc(len); 13 edge[len].point:=y; 14 edge[len].next:=p[x]; 15 p[x]:=len; 16 end; 17 18 function find(x:longint):longint; 19 var y,i:longint; 20 begin 21 i:=p[x]; 22 while i<>-1 do 23 begin 24 y:=edge[i].point; 25 if not v[y] then 26 begin 27 v[y]:=true; 28 if (cy[y]=-1) or (find(cy[y])=1) then 29 begin 30 cx[x]:=y; 31 cy[y]:=x; 32 exit(1); 33 end; 34 end; 35 i:=edge[i].next; 36 end; 37 exit(0); 38 end; 39 40 begin 41 readln(g,b,m); 42 while (b<>0) do 43 begin 44 inc(t); 45 fillchar(a,sizeof(a),false); 46 len:=0; 47 fillchar(p,sizeof(p),255); 48 for i:=1 to m do 49 begin 50 readln(x,y); 51 a[x,y]:=true; 52 end; 53 for i:=1 to g do 54 for j:=1 to b do 55 if not a[i,j] then add(i,j); 56 fillchar(cx,sizeof(cx),255); 57 fillchar(cy,sizeof(cy),255); 58 ans:=0; 59 for i:=1 to g do 60 if cx[i]=-1 then 61 begin 62 fillchar(v,sizeof(v),false); 63 ans:=ans+find(i); 64 end; 65 writeln('Case ',t,': ',b+g-ans); 66 readln(g,b,m); 67 end; 68 end.