poj3692

首先这道题很容易想到二分图相关(给的很明确了);

但是我们发现,男孩之间都互相认识,女孩之间也互相认识

这样是不能划分点集的

但是男孩之间都互相认识,女孩之间也互相认识,所以男孩和男孩,女孩和女孩之间不存在不认识关系;

如果以不认识作为边的话,这样不就能划开点集吗?

于是我们换一个思维,要找最多的男女生互相认识,不就是找最多的男女生之间不存在不认识关系吗

所以,我们在不认识之间的男女之间连边,然后对这个二分图求最大独立集即可

最大独立集=点集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.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473239.html