poj 3275 Ranking the Cows 传递闭包+邻接表优化

题目大意

  FJ想按照奶牛产奶的能力给她们排序。现在已知有N头奶牛(1 ≤ N ≤ 1,000)。FJ通过比较,已经知道了M(1 ≤ M ≤10,000)对相对关系。每一对关系表示为“X Y”,意指X的产奶能力强于Y。现在FJ想要知道,他至少还要调查多少对关系才能完成整个排序。

 

分析

  如果排序可以确定了,就是任意两头牛之间的关系都可以确定了。N头奶牛一共有C(N, 2) = N * (N - 1) / 2对关系。由现在已知的关系如能确认K对关系,则要调查的次数就是C(N, 2) - K。

  那就变成了求有多少对点连通,用Floyd求传递闭包,但是n<=1000,用普通的Floyd会超时。思考一下就会发现,枚举中间节点K之后就开始枚举起点和终点I、J,若I与K,或者J与K之间根本就不联通,那么绝对无法松弛。所以说更高效的方式就是起点只检查能通向K的节点,终点只检查K能通向的节点,这样就会把复杂度大大降低。(用邻接表)

 

代码

const
  maxv=10050;
  maxe=1500;

var
  d,d1:array[1..maxe,0..maxv] of longint;
  f:array[0..2000,0..2000] of boolean;
  i,j,k,x,y:longint;
  n,m:longint;
  ans:longint;

begin
  read(n,m);
  ans:=m;
  for i:=1 to m do
    begin
      readln(x,y);
      f[x,y]:=true;
      d[x,0]:=d[x,0]+1;
      d[x,d[x,0]]:=y;
      d1[y,0]:=d1[y,0]+1;
      d1[y,d1[y,0]]:=x;
    end;
  for k:=1 to n do
    for i:=1 to d1[k,0] do
      begin
        x:=d1[k,i];
        for j:=1 to d[k,0] do
          begin
            y:=d[k,j];
            if not f[x,y]
              then
                begin
                  d[x,0]:=d[x,0]+1;
                  d[x,d[x,0]]:=y;
                  d1[y,0]:=d1[y,0]+1;
                  d1[y,d1[y,0]]:=x;
                  f[x,y]:=true;
                  ans:=ans+1;
                end;
          end;
      end;
  write(n*(n-1) div 2-ans);
end.


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值