bzoj2535 2109

时间:2023-03-09 16:09:18
bzoj2535 2109

做过4010这题其实就水了

把图反向之后直接拓扑排序做即可,我们可以用链表来优化

每个航班的最小起飞序号就相当于在反向图中不用这个点最迟到哪

 type node=record
po,next:longint;
end; var e:array[..] of node;
ans,p,h,suc,du,d,a:array[..] of longint;
i,x,y,n,m:longint; procedure add(x,y:longint);
begin
e[i].po:=y;
e[i].next:=p[x];
p[x]:=i;
end; procedure merge(x,y:longint);
begin
if h[x]= then h[x]:=h[y]
else begin
x:=h[x];
while suc[x]<> do x:=suc[x];
suc[x]:=h[y];
end;
end; function min(wh:longint):longint;
var i,x,y,t,b:longint;
begin
for i:= to n do
begin
du[i]:=d[i];
h[i]:=;
end;
for i:= to n do
if (i<>wh) and (d[i]=) then
begin
suc[i]:=h[a[i]];
h[a[i]]:=i;
end;
t:=n;
while t> do
begin
x:=h[t];
if x= then exit(t);
h[t]:=suc[h[t]];
i:=p[x];
while i<> do
begin
y:=e[i].po;
dec(du[y]);
if (y<>wh) and (du[y]=) then
begin
if a[y]<t then b:=a[y]
else b:=t;
suc[y]:=h[b];
h[b]:=y;
end;
i:=e[i].next;
end;
merge(t-,t);
dec(t);
end;
exit();
end; procedure work1;
var i,x,y,t,b:longint;
begin
for i:= to n do
begin
du[i]:=d[i];
h[i]:=;
end;
for i:= to n do
if d[i]= then
begin
suc[i]:=h[a[i]];
h[a[i]]:=i;
end;
t:=n;
while t> do
begin
x:=h[t];
ans[t]:=x;
h[t]:=suc[h[t]];
i:=p[x];
while i<> do
begin
y:=e[i].po;
dec(du[y]);
if du[y]= then
begin
if a[y]<t then b:=a[y]
else b:=t;
suc[y]:=h[b];
h[b]:=y;
end;
i:=e[i].next;
end;
merge(t-,t);
dec(t);
end;
for i:= to n- do
write(ans[i],' ');
writeln(ans[n]);
end; procedure work2;
var i:longint;
begin
for i:= to n- do
write(min(i),' ');
writeln(min(n));
end; begin
readln(n,m);
for i:= to n do
begin
read(a[i]);
if a[i]>n then a[i]:=n;
end;
for i:= to m do
begin
readln(x,y);
add(y,x);
inc(d[x]);
end;
work1;
work2;
end.