二叉堆(一):基础
原来对堆虽然理论比较了解但只打过几个堆排序,最近复习一下吧。
POJ3253
{ FJ要把一条木棒切成给定长度的n根木条,每次的花费是木棒的长度,求总花费 和合并果子基本一样,但是题目描述是逆向的,需要一点思考,可以把切割看成合并,贪心得合并最小的木条并记录最花费 虽然用队列是最优的,但就用来练习基本的heap操作吧,支持下滤,返回并删除最小元 2011-06-19 22:41 } var a:array[0..1000000] of longint; heapsize:longint; m,n,min1,min2:longint; i,j,k:longint; ans:int64; procedure heap_down(k:longint); var i,x:longint; begin x:=a[k]; i:=k*2; while i<=heapsize do begin if (i<heapsize)and(a[i]>a[i+1]) then inc(i); if a[i]<x then begin a[k]:=a[i]; k:=i; i:=i*2; end else break; end; a[k]:=x; end; procedure swap(var a,b:longint); var c:longint; begin c:=a; a:=b; b:=c; end; function get_min:longint; var x:longint; begin swap(a[1],a[heapsize]); dec(heapsize); heap_down(1); exit(a[heapsize+1]); end; procedure insert(key:longint); var i:longint; begin inc(heapsize); i:=heapsize; while a[i div 2]>key do begin a[i]:=a[i div 2]; i:=i div 2; end; a[i]:=key; end; begin readln(n); for i:=1 to n do read(a[i]); heapsize:=n; for i:=heapsize div 2 downto 1 do heap_down(i); for i:=1 to n-1 do begin min1:=get_min; min2:=get_min; inc(ans,min1+min2); insert(min1+min2); end; writeln(ans); end.
POJ2051(WA的代码)
{ 题意:输入N个任务编号和延时,每次执行任务后任务的延时会增加开始时的延时,按顺序输出前M个任务执行的编号(延时一样时按编号顺序)。 建一个小根堆。每次输出堆顶元素并增加堆顶元素关键字的值并下滤即可 不知为什么WA 2011-06-19 22:15 } type data=record delay,time,num:longint end; var a:array[0..100000] of data; i,j,k,m,n:longint; s:string[7]; c:char; procedure heap_down(k:longint); var x:data; i:longint; begin x:=a[k]; i:=k*2; while i<=n do begin if (i<n) and ( (a[i].delay>a[i+1].delay) or ( (a[i].delay=a[i+1].delay) and (a[i].num>a[i+1].num) ) ) then inc(i); if x.delay>a[i].delay then begin a[k]:=a[i]; k:=i; i:=i*2; end else break; end; a[k]:=x; end; procedure inc_key(k,add:longint); begin inc(a[k].delay,add); heap_down(1); end; begin while not eof do begin n:=0; fillchar(a,sizeof(a),0); read(c); while c='R' do begin read(c,c,c,c,c,c,c); inc(n); readln(a[n].num,a[n].time); a[n].delay:=a[n].time; read(c); end; readln(m); for i:=n div 2 downto 1 do heap_down(i); for i:=1 to m do begin writeln(a[1].num); inc_key(1,a[1].time); end; end; end.