[Usaco2011 Nov]Cow Steeplechase奶牛越野跑

题目大意:给出N平行于坐标轴的线段,要你选出尽量多的线段使得这些线段两两没有交点(顶点也算),横的与横的,竖的与竖的线段之间保证没有交点,输出最多能选出多少条线段。(N<=250)

Input


4 5 10 5 
6 2 6 12 
8 3 8 5
 

Output

2

我们将横的线段和竖的线段分开,如果某条横的线段与竖的线段有焦点,就将他们连边。最后的答案表示最大独立集。
CODE:

type
  shu=record
   x,y1,y2:longint;
  end;
type
  heng=record
   y,x1,x2:longint;
  end;
var
  h:array[0..250] of heng;
  s:array[0..250] of shu;
  point:array[0..250] of longint;
  line:array[0..250,0..250] of boolean;
  can,b:array[0..250] of boolean;
  n,ans,htot,stot:longint;

  function find(x:longint):boolean;
  var j:longint;
  begin
     for j:=1 to stot do
      if (can[j]) and (line[x,j]) then
      begin
        can[j]:=false;
        if (point[j]=0) or (find(point[j])) then
        begin
          point[j]:=x;
          exit(true);
        end;
      end;
     exit(false);
  end;

  procedure work;
  var i,j:longint;
  begin
   for i:=1 to htot do
    begin
      for j:=1 to stot do
       if (s[j].x>=h[i].x1) and (s[j].x<=h[i].x2)
       and (h[i].y>=s[j].y1) and (h[i].y<=s[j].y2) then
            line[i,j]:=true;
    end;
  end;

  procedure init;
  var i,j,k,x1,x2,y1,y2:longint;
  begin
   fillchar(line,sizeof(line),false);
   readln(n); htot:=0; stot:=0; ans:=0;
   for i:=1 to n do
   begin
    readln(x1,y1,x2,y2);
    if x1=x2 then
    begin
      inc(stot);
      s[stot].x:=x1;
      if y1<y2 then
      begin
        s[stot].y1:=y1;
        s[stot].y2:=y2;
      end
      else
      begin
        s[stot].y1:=y2;
        s[stot].y2:=y1;
      end;
    end
    else
    begin
      inc(htot);
      h[htot].y:=y1;
      if x1<x2 then
      begin
        h[htot].x1:=x1;
        h[htot].x2:=x2;
      end
      else
      begin
        h[htot].x1:=x2;
        h[htot].x2:=x1;
      end;
    end;
   end;
   work;
   for i:=1 to htot do
   begin
    fillchar(can,sizeof(can),1);
    if find(i) then inc(ans);
   end;
   writeln(n-ans);
  end;
begin
 init;
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值