您的位置:首页 > 其它

查错 CH Round #57 - Story of the OI Class

2014-11-02 00:16 197 查看
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2357%20-%20Story%20of%20the%20OI%20Class/查错

题解:刚开始看见立马以为是 p1790拓扑编号,于是改了下输出就交了。。。

然后就爆零了。。。

仔细看题发现:

本题要求 尽早处理编号小的点

尽量使编号小的点最早被处理

难道不一样?

后来发现了 p1790的样例:

5 4

4 1

1 3

5 3

2 5

然后就明白了

对p1790来说,要想1号尽早被处理,第一次就得处理4

而本题要求处理顺序最小 那么第一次处理的必须得是2

然后就呵呵了

所以这两题的解法分别是:

本题:正向贪心,每次选取入度为0的且编号最小的点

p1790:反向贪心,反向建图,每次选取出度为0且编号最大的点

代码:(本题)

var head,q,next,go,a,f,outp:array[0..201000] of longint;
i,h,t,n,m,x,y,l,tot:longint;
function get:longint;
var i,k:longint;
begin
get:=a[1];
a[0]:=a[l];dec(l);
i:=1;k:=2;
while k<=l do
begin
if (k<l) and (a[k]<a[k+1]) then inc(k);
if (a[0]<a[k]) then begin a[i]:=a[k];i:=k;k:=k<<1;end
else k:=l+1;
end;
a[i]:=a[0];
end;
procedure put(x:longint);
var i,k:longint;
begin
inc(l);
a[0]:=x;
i:=l;k:=l>>1;
while k>=1 do
begin
if a[0]>a[k] then begin a[i]:=a[k];i:=k;k:=k>>1;end
else k:=0;
end;
a[i]:=x;
end;
procedure init;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
go[i]:=x;
next[i]:=head[y];
head[y]:=i;
inc(outp[x]);
end;
end;
procedure main;
begin
h:=0;t:=0;
for i:=1 to n do
if outp[i]=0 then
put(i);
tot:=n;
while l<>0 do
begin
x:=get;
f[x]:=tot;dec(tot);
i:=head[x];
while i<>0 do
begin
y:=go[i];
dec(outp[y]);
if outp[y]=0 then put(y);
i:=next[i];
end;
end;
for i:=1 to n do write(f[i],' ');
end;
begin
init;
main;
end.


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: