看到这题可以发现是二分图最短路径覆盖问题,其实我们可以这样建图。以垃圾点为节点,若能从i走到j则连一条边,这样二分图就建起来了。
(刚刚翻看了一下discuss,发现本题还有一个贪心的神解法,似乎要用到偏序集上的Dilworth定理,做法与poj1065,3636类似)
var
k:longint;
a:array[1..1000,1..2]of longint;
g:array[1..1000,1..1000]of longint;
t,match:array[1..1000]of longint;
h:array[1..1000]of boolean;
procedure init;
var i,j:longint;
begin
fillchar(match,sizeof(match),0);
fillchar(t,sizeof(t),0);
k:=1;
while(a[k][1]<>0)do
begin
inc(k);
readln(a[k][1],a[k][2]);
if(a[k][1]=0)then
begin
dec(k);
break;
end;
end;
for i:=1 to k do
for j:=1 to k do
if(i<>j)then
begin
if(a[j][1]>=a[i][1])and(a[j][2]>=a[i][2])then
begin
inc(t[i]);g[i,t[i]]:=j;
end;
end;
end;
function check(k:longint):boolean;
var i:longint;
begin
for i:=1 to t[k] do
if(not h[g[k,i]])then
begin
h[g[k,i]]:=true;
if(match[g[k,i]]=0)or(check(match[g[k,i]]))then
begin
match[g[k,i]]:=k;exit(true);
end;
end;
exit(false);
end;
function hungarian:longint;
var i,ans:longint;
begin
ans:=0;
for i:=1 to k do
begin
fillchar(h,sizeof(h),0);
if(check(i))then inc(ans);
end;
exit(ans);
end;
begin
readln(a[1][1],a[1][2]);
while(a[1][1]<>-1)do
begin
init;
writeln(k-hungarian);
readln(a[1][1],a[1][2]);
end;
end.