三条线_纪中2929_最小覆盖

Description

为了监视他的N (1 <= N <= 50,000)头奶牛,Farmer John购买了新的监视系统。第i头奶牛位置在(x_i, y_i),坐标为整数,范围0..1,000,000,000。任意两头奶牛的位置不同。

FJ的监视系统有三个摄像头,每个摄像头只能监视一条水平线或者垂直线上的所有奶牛。请计算如果FJ安装好这三个摄像头,能否监视所有的N头奶牛。也就是说,计算N头奶牛的位置,是否可以被三条直线“覆盖”,直线必须是水平线或垂直线。

Input

第1行:一个整数N。

第2..N+1行:第i+1行包含空格隔开的整数x_i 和y_i,给定第i头奶牛的位置。

Output

第1行:如果使用三个摄像头,能监视所有的N头奶牛,请输出1。否则,输出0。

Sample Input

6

1 7

0 0

1 2

2 0

1 4

3 4

Sample Output

1

Hint

【样例解释】

使用水平线y=0, 垂直线x=1和y=4。它们包含所有的N头奶牛位置。

想法

也就又是乱搞,画个图发现这道题目类似于之前做过的poj3041_戳这里蜜汁传送门
小行星变成了母牛也是够了
不同的是加上了限制条件,只能扫射三次,数据规模很大,很大很大
于是乎就想到了离散+匹配求最小覆盖
媳妇 XXOO着就搞出来了

忘得差不多了,还是不够熟练

乱搞的成果:

type
  edge=record
    x,y,next:Longint;
  end;
  arr=array[-1..50000]of longint;
var
  e:array[-1..50000]of edge;
  vis:array[-1..50000]of boolean;
  a,b,qa,qb,ra,rb,ls,link:arr;
  maxE,n:longint;
procedure add(x,y:Longint);
begin
  inc(maxE);
  e[maxE].x:=x;
  e[maxE].y:=y;
  e[maxE].next:=ls[x];
  ls[x]:=maxE;
end;
procedure qsort(var v,g:arr;l,r:longint);
var
  x,y,key,temp:longint;
begin
  if l>=r then exit;
  x:=l;
  y:=r;
  key:=v[l+random(r-l+1)];
  repeat
    while  (v[x]<key) do inc(x);
    while  (v[y]>key) do dec(y);
    if x<=y then
    begin
      temp:=v[x];v[x]:=v[y];v[y]:=temp;
      temp:=g[x];g[x]:=g[y];g[y]:=temp;
      inc(x);
      dec(y);
    end;
  until x>y;
  qsort(v,g,l,y);
  qsort(v,g,x,r);
end;
function find(x:Longint):boolean;
var
  i,p:longint;
begin
  find:=true;
  i:=ls[x];
  while i>0 do
  with e[i] do
  begin
    if not vis[y] then
    begin
      p:=link[y];
      link[y]:=x;
      vis[y]:=true;
      if (p=0)or(find(p)) then exit;
      link[y]:=p;
    end;
    i:=next;
  end;
  find:=false;
end;
procedure main;
var
  i,ans:longint;
begin
  ans:=0;
  fillchar(link,sizeof(link),0);
  for i:=1 to n do
  begin
    fillchar(vis,sizeof(vis),false);
    if find(i) then inc(ans);
  end;
  if (ans<=3)and(ans>=0) then
  writeln(1)
  else
  writeln(0);
end;
procedure init;
var
  i,k,l:longint;
begin
  maxE:=0;
  fillchar(ls,sizeof(ls),0);
  fillchar(e,sizeof(e),0);
  readln(n);
  for i:=1 to n do
  begin
    readln(a[i],b[i]);
    inc(a[i]);
    inc(b[i]);
    ra[i]:=i;
    rb[i]:=i;
  end;
  qsort(a,ra,1,n);
  qsort(b,rb,1,n);
  k:=0;l:=k;
  for i:=1 to n do
  begin
    if a[i]<>a[i-1] then inc(k);
    if b[i]<>b[i-1] then inc(l);
    qa[ra[i]]:=k;
    qb[rb[i]]:=l;
  end;
  for i:=1 to n do
  add(qa[i],qb[i]);
end;
begin
  randomize;
  init;
  main;
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值