查错(拓扑排序+堆维护)

来源:互联网 发布:专业的音频软件 编辑:程序博客网 时间:2024/06/01 10:01

不了解堆的可以打开链接看看基础代码:http://wenku.baidu.com/link?url=8VzUPoY188woWI_TKltWXyJPnng2idVsSyw-zl9bcreKHweGACPWB1h97ZEjri8xxrhBt-63XAfLLsmUiIlmzLCZnMzN_djx1jocwcPZt_S

拓扑排序 :

由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。

(1) 选择一个入度为0的顶点并输出之;

(2) 从网中删除此顶点及所有出边。

循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。 (摘自 : 百度百科)

查错
[Description] 一天,考试题神坑了。不过,我们的 Mosaic 还是成功的写出了程序,当然,结果比较赞: “TBMW*TBMW*”,结果被痛骂了一顿。经过漫长的检查,Mosaic 发现他的程序有 M 处错误, 现在要做的就是修改程序了。但是他发现,这 M 处错误存在复杂的联系,有的错误必须在其他 错误之前改正,否则事情会变得很麻烦,因此,他开始写另一个程序来解决这个问题……

[Input] 第一行两个整数:M,N。N 表示程序之间的依赖关系数量 以下 N 行每行两个整数 a,b。表示第 a 处错误必须在第 b 处错误之前改正。

[Output] 一行,按改正顺序输出错误编号。若有多解,请输出字典序小的解(即尽量使编号小的错误 先被改正)。如果无解,输出“OMG.”(不含引号)。

[Sample] Sample Input
5 5
1 2
2 3
1 3
1 4
4 5
Sample Output
1 2 3 4 5

[Hint] 对于 100%的数据,有 0 < M,N ≤ 100000 保证没有重边。

program df;
type point=^node;
node=record
date,ends:longint;
next:point;
end;
var i,j,n,m,x,y,z,k,t,len:longint;
p:point;
path:array[0..100000] of point;
a,c,d,e,f:array[0..100000] of longint;
tm:array[0..1000000] of longint;
b,zhan,re:array[0..100000] of boolean;

procedure com(x,y:longint);
var i:point;
begin
i:=path[x];
new(path[x]);
path[x]^.ends:=y;
path[x]^.next:=i;
end;

procedure put(x:longint); //维护度数为零的点中的最小值
var i,j:longint;
begin
inc(len);
a[len]:=x;
i:=len;
while (a[i div 2]>a[i]) and (i>1) do
begin
j:=a[i]; a[i]:=a[i div 2]; a[i div 2]:=j;
i:=i div 2;
end;
end;

function get:longint;
var i,j,d:longint;
begin
get:=a[1];
a[1]:=a[len];
dec(len);
i:=1;
while i*2<=len do
begin
if a[i*2]>a[i*2+1] then j:=i*2+1
else j:=i*2;
if a[i]>a[j] then
begin
d:=a[j]; a[j]:=a[i]; a[i]:=d;
end;
i:=j;
end;
end;

procedure dfs;
var i:point;
x,y:longint;
begin
while len>0 do
begin
x:=get;
inc(t);
c[t]:=x; //作为最小值取出
i:=path[x];
while (i<>nil) do //将相连的边删去,继续找度数为零的
begin
y:=i^.ends;
dec(d[y]);
if d[y]=0 then put(y);
i^.ends:=0;
i:=i^.next;
end;
end;
end;

begin
assign(input,’correct.in’);
reset(input);
assign(output,’correct.out’);
rewrite(output);
readln(n,m);
for i:=1 to m do
begin
readln(x,y);
com(x,y);
inc(d[y]);
end;
len:=0; t:=0;
for i:=1 to n do
if d[i]=0 then put(i);
dfs;
if t=n then
for i:=1 to t do
write(c[i],’ ‘);
if t<>n then writeln(‘OMG.’); //说明有环
close(input);
close(output);
end.

0 0
原创粉丝点击