您的位置:首页 > 其它

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

2016-04-23 10:12 302 查看
题目大意

  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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: