Description
GGF最近经常遭到不明导弹的袭击,因此他只好开发了一套导弹拦截系统。
该系统非常先进,使用会拐弯的激光对导弹进行射击。-_-
所有被激光击中的导弹就瞬间完蛋,而且一束激光可以同时摧毁多枚导弹。
但激光只能向上发射,所以若同一束激光能依次击中多枚导弹,则这些导弹坐标的每一维都严格单调上升。建立了一个三维坐标系后:
假设4枚导弹坐标为:(0, 0, 0) (1, 1, 0) (1, 1, 1), (2, 2, 2)
则一束激光可以依次击毁1,3,4号导弹,却不能依次击毁1,2,4,也不能依次击毁4,3,1。
现在,GGF发现N枚导弹正向自己飞来。-_-
在定位了导弹的坐标后,他想知道,只发射一束激光最多可以摧毁多少枚导弹,若要摧毁所有导弹,至少需要发射多少束激光。(激光速度极快,所以可以认为导弹在那一瞬间静止,而且激光间不相互影响)
Input
输入文件第一行一个正整数N(1<=N<=2000)。
下面N行,每行3个整数Xi,Yi,Zi(0<=Xi,Yi,Zi<=10^6) ,描述一个导弹的坐标。
Output
两行,第一行一个整数表示最多可以拦截多少枚导弹。
第二行一个整数表示最少发射多少束激光才能拦截全部导弹。
Sample Input
4
1 2 3
1 1 1
2 5 4
0 1 1
Sample Output
3
2
Data Constraint
Hint
【数据规模】
对于20%的数据,有N<=10。
对于50%的数据,有N<=300。
对于100%的数据如题。
题解
发现导弹的打击关系可以变成一个无环dag
那么最多打多少导弹就是求dag中的最长路径。
多少套系统就是求最小路径覆盖。
最小路径覆盖=n-最大匹配。
所以跑一遍bfs和匈牙利即可。
type aa=record
x,y,z:longint;
end;
var n,i,j,k,l,tot,tot1,ans:longint;
d,head,head1,f,bz,g,r:array[0..100000]of longint;
next,next1,t,t1:array[0..4000000]of longint;
a:array[0..100000]of aa;
procedure sort(l,r:longint);
var i,j,kx,ky,kz:longint;
begin
i:=l;
j:=r;
kx:=a[(l+r)div 2].x;
ky:=a[(l+r)div 2].y;
kz:=a[(l+r)div 2].z;
repeat
while (a[i].xor((a[i].x=kx)and(a[i].yor((a[i].x=kx)and(a[i].y=ky)and(a[i].zdo inc(i);
while (a[j].x>kx)or((a[j].x=kx)and(a[j].y>ky))or((a[j].x=kx)and(a[j].y=ky)and(a[j].z>kz)) do dec(j);
if i<=j then begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if ithen sort(i,r);
if j>l then sort(l,j);
end;
procedure ad(x,y:longint);
begin
inc(tot);
next[tot]:=head[x];
head[x]:=tot;
t[tot]:=y;
end;
procedure ad1(x,y:longint);
begin
inc(tot1);
next1[tot1]:=head1[x];
head1[x]:=tot1;
t1[tot1]:=y;
end;
procedure bfs;
var i,j,k,l:longint;
begin
k:=0;
for i:=1 to n do if r[i]=0 then begin
inc(k);
d[k]:=i;
f[i]:=1;
end;
i:=0;
while ido begin
inc(i);
j:=head[d[i]];
while j<>0 do begin
f[t[j]]:=f[d[i]]+1;
dec(r[t[j]]);
if r[t[j]]=0 then begin
inc(k);
d[k]:=t[j];
end;
j:=next[j];
end;
end;
ans:=f[d[n]];
end;
function dfs(x:longint):longint;
var j:longint;
begin
if bz[x]=i then exit(0);
bz[x]:=i;
j:=head1[x];
while j<>0 do begin
if (g[t1[j]]=0)or(dfs(g[t1[j]])=1) then begin
g[t1[j]]:=x;
exit(1);
end;
j:=next1[j];
end;
exit(0);
end;
begin
readln(n);
for i:=1 to n do readln(a[i].x,a[i].y,a[i].z);
sort(1,n);
for i:=2 to n do begin
for j:=1 to i-1 do begin
if (a[i].x>a[j].x)and(a[i].y>a[j].y)and(a[i].z>a[j].z) then begin
ad(j,i);
inc(r[i]);
ad1(j,i+n);
end;
end;
end;
bfs;
writeln(ans);
ans:=0;
for i:=1 to n do ans:=ans+dfs(i);
writeln(n-ans);
end.