1. Trang chủ
  2. » Luận Văn - Báo Cáo

CHUYÊN đề cấu TRÚC dữ LIỆU HEAP

35 1.7K 4

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Cấu trúc

  • MỤC LỤC

  • Khái niệm

  • Các thao tác thường dùng đối với Heap Max

    • Khai báo

    • UpHeap

    • DownHeap

    • Push

    • Pop

    • Dijkstra Heap

  • Một số bài tập ứng dụng

    • 1. Bài tập 1: Heapuri

    • 2. Bài tập 2: Thả xốp

    • 3. Bài tập 3:PILOT

    • Bài tập4:Tiểu thuyết trinh thám

    • Bài tập 5: Cezar

    • Bài tập 6:Toy Cars

    • Bài tập 7:BASE3

      • Yêu cầu:

      • INPUT: BASE3.INP

      • OUTPUT: BASE3.OUT

      • Giới hạn

      • Ví dụ:

  • Một số bài tập vận dụng

    • Bài tập 1: BOCSOI13

    • Bài tập 2: Kế hoạch làm bài

    • Bài tập 3: CATUN

    • Bài tập 3: Barbar

    • Bài tập 4:Cầu cảng

    • 4. Bài tập 5:K TỔNG BÉ NHẤT

    • Bài tập 6: BINLADEN

  • Tài liệu tham khảo

Nội dung

MỤC LỤC MỤC LỤC...............................................................................................................................1 Khái niệm................................................................................................................................2 Các thao tác thường dùng đối với Heap Max.........................................................................2 Khai báo..............................................................................................................................2 UpHeap................................................................................................................................2 DownHeap...........................................................................................................................3 Push.....................................................................................................................................4 Pop.......................................................................................................................................4 Dijkstra Heap.......................................................................................................................5 Một số bài tập ứng dụng.........................................................................................................6 1.Bài tập 1: Heapuri............................................................................................................6 2.Bài tập 2: Thả xốp............................................................................................................8 3.Bài tập 3:PILOT.............................................................................................................10 Bài tập4:Tiểu thuyết trinh thám........................................................................................13 Bài tập 5: Cezar ................................................................................................................18 Bài tập 6:Toy Cars............................................................................................................22 Bài tập 7:BASE3 ..............................................................................................................26 Một số bài tập vận dụng........................................................................................................30 Bài tập 1: BOCSOI13.......................................................................................................30 Bài tập 2: Kế hoạch làm bài..............................................................................................31 Bài tập 3: CATUN............................................................................................................31 Bài tập 3: Barbar...............................................................................................................32 Bài tập 4:Cầu cảng............................................................................................................33 4.Bài tập 5:K TỔNG BÉ NHẤT.......................................................................................33 Bài tập 6: BINLADEN......................................................................................................34 Tài liệu tham khảo.................................................................................................................35 1 CHUYÊN ĐỀ: CẤU TRÚC DỮ LIỆU HEAP Khái niệm Heap là một trong những cấu trúc dữ liệu đặc biệt quan trọng, nó giúp ta có thể giải được nhiều bài toán trong thời gian cho phép. Độ phức tạp thông thường khi làm việc với Heap là O(logN). Heap thực chất là một cây cân bằng thỏa mãn các điều kiện sau: • Một nút có không quá 2 nút con. • Với Heap Max thì nút gốc là nút lớn nhất, mọi nút con đều không lớn hơn nút cha của nó. Với Heap Min thì ngược lại. Mặc dù được mô tả như cây nhưng Heap có thể được biểu diễn bằng mảng. Nút con của nút i là 2*i và 2*i+1. Do Heap là cây cân bằng nên độ cao của 1 nút luôn nHeap then exit; // Nếu i không có nút con thì không làm việc if (j < nHeap) and (Heap[j] < Heap[j+1]) then Inc(j); // Nếu i có 2 nút con thì chọn nút ưu tiên hơn if Heap[i] < Heap[j] then // Nếu nút cha nhỏ hơn nút con begin swap(Heap[i] , Heap[j]); // Đổi chỗ 2 phần tử trong Heap DownHeap(j); // Tiếp tục di chuyển xuống dưới end; end; Push Đưa 1 phần tử mới vào Heap: Thêm 1 nút vào cuối Heap và tiến hành UpHeap từ đây: Procedure Push(x : LongInt); Begin Inc(nHeap); // Tăng số phần tử của Heap Heap[nHeap] := x; // Thêm x vào Heap UpHeap(nHeap); End; Pop Rút ra 1 phần tử ở vị trí v trong Heap: Gán Heap[v] := Heap[nHeap] rồi tiến hành chỉnh lại Heap: Function Pop(v : LongInt) : LongInt; Begin Pop := Heap[v]; // Lấy phần tử ở vị trí v ra khỏi Heap Heap[v] := Heap[nHeap]; // Đưa phần tử ở cuối Heap vào vị trí v Dec(nHeap); // Giảm số phần tử của Heap đi 1 4 {Chỉnh lại Heap} UpHeap(v); DownHeap(v); End; Ngoài ra, khi sử dụng thuật toán Dijkstra/Prim kết hợp cấu trúc Heap, bạn còn có thể sử dụng cách Push và Pop khác thuận lợi hơn so với cách trình bày ở trên: Dijkstra Heap 1/ Update – Dijkstra: Procedure Update(v : LongInt); // Đỉnh v vừa được sửa nhãn, cần chỉnh lại Heap var child , parent : LongInt; begin child := pos[v]; // child là vị trí của đỉnh v trong Heap if child = 0 then // Nếu đỉnh v chưa có trong Heap begin Inc(nHeap); // Tăng số phần tử của Heap child := nHeap; // Đưa v vào cuối Heap end; parent := child div 2; // parent là nút cha của child while (parent > 0) and (d[Heap[parent]] > d[v]) do // Nếu đỉnh ở nút parent kém ưu tiên hơn v thì bị “kéo xuống” nút child begin Heap[child] := Heap[parent]; // Đẩy đỉnh được lưu trong nút cha xuống nút con pos[Heap[child]] := child; // Ghi nhận lại vị trí mới của đỉnh đó child := parent; // Tiếp tục di chuyển lên parent := child div 2; end; Heap[child] := v; // Thao tác “kéo xuống” ở trên sẽ tạo ra 1 ô trống ở nút child để đặt v vào pos[v] := child; // Ghi nhận vị trí mới của đỉnh v trong Heap end; 2/ Pop – Dijkstra: Function Pop : LongInt; // Lấy từ Heap đỉnh có nhãn tự do nhỏ nhất var r , v , c : LongInt; begin Pop := Heap[1]; // Nút gốc là nút có nhãn tự do nhỏ nhất v := Heap[nHeap]; // v là đỉnh ở nút lá cuối Heap, sẽ được đảo lên đầu và vun đống Dec(nHeap); // Giảm số phần tử của Heap r := 1; // Bắt đầu từ nút gốc while r*2 = d[v] then break; // Nếu v ưu tiên hơn thì không làm việc nữa Heap[r] := Heap[c]; // Chuyển đỉnh lưu ở nút con lên nút cha pos[Heap[r]] := r; // Cập nhật lại vị trí mới trong Heap của đỉnh đó r := c; // Tiếp tục di chuyển xuống dưới 5 end; Heap[r] := v; // Đỉnh v được đặt vào vị trí r để đảm bảo cấu trúc Heap pos[v] := r; // Ghi nhận vị trí mới của đỉnh v trong Heap end; Một số bài tập ứng dụng 1. Bài tập 1: Heapuri Cho danh sách gồm N phần tử. Chúng ta thực hiện một số thao tác trên danh sách. Có 3 loại thao tác sau : - Thao tác 1 : Cho phần tử x vào danh sách - Thao tác 2 : Xóa phần tử thứ t (theo thứ tự nhập vào) - Thao tác 3: Lấy ra phần tử nhỏ nhất trong danh sách Yêu cầu: Hãy cho biết các kết quả của thao tác 3 ? INPUT: HEAPURI.INP - Dòng 1: N - Các dòng tiếp theo là dãy thao tác cần xử lý theo định dạng 1 x, 2 x hoặc 3 tương ứng là thao tác 1, 2 và 3 OUTPUT : HEAPURI.OUT - Ghi trên nhiều dòng, mỗi dòng là kết quả của thao tác 3 theo thứ tự trong file input. Ví dụ : HEAPURI.INP HEAPURI.OUT 9 1 1 1 3 1 2 3 2 3 4 7 9 4 2 7 2 1 4 Dễ thấy đây là một danh sách động (số lượng phần tử thay đổi), vì vậy ta xây dựng một heapmin để lấy ra giá trị nhỏ nhất ở các thao tác 3. Để xóa phần tử thứ t theo thứ tự nhập vào thì ta lưu thêm một mảng Pos. #include #include #define maxn 200010 int N, L, NR; int A[maxn], Heap[maxn], Pos[maxn]; 6 void push(int x) { int aux; while (x/2 && A[Heap[x]] i then sort(i,y); end; {*------------------------------------------------------------*} {*------------------------------------------------------------*} procedureinkq; begin assign(fo,tfo);rewrite(fo); write(fo,res); close(fo); end; {*------------------------------------------------------------*} {*------------------------------------------------------------*} {*------------------------------------------------------------*} {*------------------------------------------------------------*} BEGIN randomize; nhap; 17 sort(1,n); xuli; inkq; END. Bài tập 5: Cezar Tại HT Land, có tất cả n thượng nghị sĩ ở trong n ngôi biệt thự (đánh số từ 1 đến n), giữa 2 ngôi nhà có một đường đi duy nhất: đường đi trực tiếp hoặc không trực tiếp (đi qua các con đường khác). Tất cả các ngôi nhà đều đi được đến nhau. Mỗi thượng nghị sĩ khi đi từ nhà mình đến thượng viện, phải trả 1 USD khi đi qua một con phố (phố = đường nối trực tiếp 2 nhà bất kỳ). HT – người đứng đầu thượng viện đã nghĩ cách làm sao cho số tiền mà các thượng nghĩ sĩ phải trả là tối thiểu. Vì vậy, HT quyết định • Có k con phố miễn phí (thượng nghị sĩ sẽ không phải trả tiền khi đi trên con phố này) • Đặt tòa nhà thượng viện ở một trong n ngôi nhà Bạn hãy viết chương trình tính xem chi phí tối thiểu là bao nhiêu? INPUT: CEZAR.INP - Dòng 1: Số nguyên n và k tương ứng là số ngôi nhà ở HT land và số đường phố miễn phí - N – 1 dòng tiếp theo, mỗi dòng chứa 2 số i j có nghĩa là có con phố nối ngôi nhà i và ngôi nhà j OUTPUT: CEZAR.OUT Chi phí tối thiểu phải trả Giới hạn: • Ví dụ CEZAR.INP 13 3 12 23 28 78 75 54 56 89 8 10 10 11 10 12 10 13 CEZAR.OUT 11 Giải thích Có nhiều phương án giải quyết: Đây là 1 phương án: – 5-7, 7-8, 8-10 là những đường miễn phí – 8 là thượng viện Chi phí tối thiểu là: 11. 18 6 3 1 4 2 5 7 8 10 9 11 12 13 Time limit:0.5 s/test Thuật toán: 1. Chúng ta sẽ tìm con đường phải trả phí đi lại. 2. Khởi tạo D[i] = trọng số của đỉnh i với ý nghĩa = số lượng người đi đến thượng viện phải đi qua con đường này. Ban đầu 3. Tại mỗi bước chúng ta sẽ cho các nút lá vào Heap, mỗi lần lấy 1 phần tử trong heap chúng ta sẽ update lại trọng số của đỉnh kề với đỉnh vừa lấy ra và nếu đỉnh vừa update thành nút lá ta lại cho vào trong heap. Sau khi lấy xong nhật đáp án. Const tfi='cezar.inp'; tfo='cezar.out'; oo = 1000000000; Type arr1=array[0..100000] of longint; arr2=array[0..100000] of boolean; arr3=array[0..15000] of longint; arr4=array[0..15000] of arr3; Var fi,fo : text; heap,head,ke,d,c,pos,cost,trace,deg : arr1; free : arr2; k,n,nheap,f,r,sum,res : longint; count : arr4; {===============================} Procedure nhap; Var i,u,v : longint; Begin Assign(fi,tfi);Reset(fi); read(fi,n,k); For i := 1 to n-1 do Begin read(fi,u,v); d[i] := u; c[i] := v; inc(deg[u]); inc(deg[v]); ENd; head[1] := deg[1]; For i := 2 to n+1 do Begin head[i] := head[i-1] + deg[i]; 19 đỉnh thì cập End; For i := 1 to n-1 do Begin u := d[i]; v := c[i]; ke[head[u]] := v; ke[head[v]] := u; cost[head[u]] := 1; cost[head[v]] := 1; dec(head[u]); dec(head[v]); End; Close(fi); End; {===============================} Procedure khoitao; Var i :longint; Begin Fillchar(free,sizeof(free),true); For i := 1 to n do BEgin pos[i] := 0; cost[i] := 1; End; nheap := 0; End; {===============================} Procedure downheap(root : longint); Var child,u : longint; BEgin u := heap[root]; repeat child := root*2; If (child cost[heap[child+1]]) then inc(child); If (child >nheap) or (cost[heap[child]]>= cost[u]) then break; heap[root] := heap[child]; pos[heap[root]] := root; root := child; Until false; heap[root] := u; pos[u] := root; End; {===============================} Procedure upheap(child : longint); Var root,u : longint; Begin u := heap[child]; 20 Repeat root := child div 2; If (root=0) or (cost[heap[root]] 0 do begin pop; if (xi = 0) then begin write(fo,d[xi,yi]); exit; end; update; end; write(fo,0) ; end ; begin assign(fi,tfi);reset(fi); assign(fo,tfo);rewrite(fo); Nhap; init; xuly; close(fi); close(fo) ; end. Một số bài tập vận dụng Bài tập 1: BOCSOI13 Bước vào tiểu học, Bé Bi được cô giáo chủ nhiệm cho làm lớp trưởng. Nhân dịp kỷ niệm ngày thành lập trường, Bé Bi tổ chức cho cả lớp chơi 1 trò chơi sau: Có N đống sỏi xếp thành một hàng, đống thứ i có A i viên sỏi. Ta có thể ghép hai đống sỏi bất kỳ thành một đống và mất một chi phí bằng 5% tổng hai đống sỏi đó. Hãy tìm cách ghép N đống sỏi này thành một đống với chi phí là nhỏ nhất. Ví dụ: Nếu chúng ta có 4 đống sỏi với số lượng sỏi là 10, 11, 12 và 13. - Bước 1: Ghép 2 đống 10 và 11 thành 1 đống có số lượng 21 (chi phí là 1.05) - Bước 2: Ghép đống 21 vừa thu được với đống 12 thành đống có số lượng 33 (chi phí 1.65) - Bước 3: Ghép đống 33 vừa thu được với đống 13 thành 1 đống cuối cùng có số lượng sỏi là 46 (chi phí 2.3) - Vậy tổng chi phí là 5.00. Tuy nhiên đây không phải là phương án ghép đống tối ưu, chúng ta có phương án ghép 4 đống này thành 1 đống với chi phí nhỏ nhất là 4.60. Các bạn hãy tìm giúp Bé Bi phương án chơi tối ưu nhé! INPUT:BOCSOI13.INP: - Dòng 1: Số nguyên dương N là số đống sỏi. - Dòng tiếp theo, ghi N số nguyên dương, tương ứng là số lượng sỏi trong từng đống. Số lượng sỏi không vượt quá 10.000. OUTPUT:BOCSOI13.OUT: - Ghi 1 số thực duy nhất là chi phí nhỏ nhất phải trả để ghép N đống sỏi thành 1 đống. Kết quả ghi dưới dạng 2 chữ số sau dấu thập phân. 30 Ví dụ: BOCSOI13.INP 4 10 11 12 13 2 11 BOCSOI13.OUT 4.60 0.10 Bài tập 2: Kế hoạch làm bài Nobita được giao n bài tập về nhà đánh số từ 1 tới n. Mỗi bài tập cần đúng 1 đơn vị thời gian để làm và tại mỗi thời điểm, Nobita chỉ có thể làm được 1 bài tập. Bài tập thứ I cần hoàn thành không muộn hơn thời điểm t i và nếu bài thứ I bị nộp muộn thì Nobita sẽ bị thày giáo cho pi điểm 0. Giả sử Nobita định làm bài tập từ thời điểm a đến hết thời điểm b. Hãy giúp Nobita lên kế hoạch làm bài tập để số điểm 0 phải nhận là ít nhất. INPUT: PENALTY.INP - Dòng 1: Chứa 3 số nguyên dương n ; - N dòng tiếp theo, dòng thứ I chứa hai số nguyên dương ti, pi OUTPUT: PENALTY.OUT Một số duy nhất là số điểm 0 tối thiểu phải nhận Ví dụ: PENALTY.INP PENALTY.OUT Giải thích 5 1 4 25 Làm bài 1 từ thời điểm 1 đến thời điểm 2. 2 100 Làm bài 4 từ thời điểm 2 đến thời điểm 3. 2 20 4 5 Làm bài 5 từ thời điểm 3 đến thời điểm 4. 4 10 Bài 2 và bài 3 bị nộp muộn 4 6 Bài tập 3: CATUN Tại vương quốc HT có N thị trấn đánh số từ 1 đến N và M con đường nối 2 thị trấn bất kỳ. Trong số N thị trấn thì có K thị trấn là pháo đài chống giặc ngoại xâm. Khi có giặc ngoại xâm, 1 pháo đài bất kỳ sẽ bảo vệ những thị trấn gần nó nhất. Nếu co 1 thị trấn nào đó có khoảng cách tới 2 pháo đài bằng nhau thì thị trấn này được bảo vệ bởi pháo đài có chỉ số nhỏ hơn? INPUT: CATUN.IN - Dòng 1: N, M và K ( - Dòng 2: K số nguyên dương là chỉ số của K pháo đài M dòng tiếp theo, mỗi dòng ghi 3 số x, y, z có nghĩa là có con đường 2 chiều nối thị trấn x với thị trấn y có chiều dài là z. OUTPUT: CATUN.OUT 31 - Ghi N số nguyên dương, số thí I là chỉ số của pháo đài bảo vệ thị trấn i. Nếu thị trấn I không được bảo vệ bởi pháo đài nào thì ghi số 0 Ví dụ: CATUN.IN 8 9 2 2 5 1 3 6 1 5 3 1 6 1 2 3 9 5 6 5 6 8 7 3 6 2 4 7 1000 2 8 5 Time limit: 0.2s CATUN.OUT 5 0 5 0 0 5 0 2 Bài tập 3: Barbar Sau cuộc chiến tranh thần thánh, HT bị bắt giam vào ngục tối là một bảng cỡ R*C (R dòng và C cột). Tại một ô có thể di chuyển sang 4 ô kề cạnh. Trong ngục có 1 số ô là có thể di chuyển tự do, một số ô là tường không thể di chuyển qua và đặc biệt một số ô bị chiếm giữ bởi các con rồng lửa (không thể đi lại gần nếu không muốn bị cháy thành than). Bạn hãy giúp HT di chuyển qua ngục tối sao cho khoảng cách ngắn nhất đến các con rồng lửa là lớn nhất? INPUT: BARBAR.IN - Dòng 1: R và C ( - R dòng tiếp theo, mỗi dòng ghi C ký tự biểu diễn ngục tối. “.” Ô di chuyển tự do “*” Tường “D” Rồng lửa “I”: Vị trí xuất phát của HT “O”: Vị trí thoát khỏi ngục tối OUTPUT: BARBAR.OUT - Một số duy nhất là giá trị lớn nhất của khoảng cách ngắn nhất đến các con rồng lửa khi HT di chuyển ra khỏi ngục tối. Nếu không có cách di chuyển ghi -1 Ví dụ: Giải thích BARBAR.IN BARBAR.OUT .......... 10 10 2 .Iooo.D... ....o..... ..D.o.D... .*..oo.... D*...ooooo *...D....o .......... .I....D... .......... ..D...D... .*........ D*........ 32 *...D..... ..****.... ...O...... .......... ..****...o ...Ooooooo .......... Time limit: 0.4s Bài tập 4:Cầu cảng Một cầu cảng có m cầu cảng để tiếp nhận các tàu cập bến. Tại một thời điểm, mỗi cầu cảng chỉ có thể tiếp nhận không quá 1 tàu. Ban đầu các cầu cảng đều trống và có n tàu xin đăng ký cập bến, tàu thứ i muốn đậu ở cảng ngày sau thời điểm tới hết thời điểm . Có thể coi thời gian tàu thứ i muốn đậu ở cảng là một khoảng trên trục thời gian. Tàu đã vào cầu cảng nào thì sẽ đậu ở đó trong suốt thời gian nằm cảng. Yêu cầu : Hãy cho biết với m cầu cảng đã cho, có thể tiếp nhận được tối đa bao nhiều tàu và chỉ ra lịch trình tiếp nhận tại mỗi cầu cảng ? INPUT:SEAPORTS.INP - Dòng 1: Chứa 2 số nguyên dương - N dòng tiếp theo, dòng thứ i chứ 2 số nguyên OUTPUT:SEAPORTS.OUT - Dòng 1 : Ghi số lượng tàu được tiếp nhận phục vụ - Dòng 2 : Ghi n số nguyên, số thứ i là số hiệu cầu cảng sẽ tiếp nhận tàu thứ i trong trường hợp tàu thứ i được tiếp nhận, còn nếu tàu thứ i không được tiếp nhận thì số thứ i là 0. Ví dụ : SEAPORTS.INP SEAPORTS.OUT 25 4 03 11220 35 02 25 14 4. Bài tập 5:K TỔNG BÉ NHẤT Cho 2 dãy số nguyên A và B. Với mọi số A[i] thuộc A và B[j] thuộc B (1 ≤ A i, Bi ≤ 109 ) người ta tính tổng nó. Tất cả các tổng này sau khi được sắp xếp không giảm sẽ tạo thành dãy C. Nhiệm vụ của bạn là: Cho 2 dãy A, B. Tìm K số đầu tiên trong dãy C INPUT: KMIN.INP - Dòng đầu tiên gồm 3 số: M, N, K (1≤M, N, K ≤ 50.000) - M dòng tiếp theo gồm M số mô tả dãy A - N dòng tiếp theo gồm N số mô tả dãy B OUTPUT:KMIN.OUT 33 - Gồm K dòng tương ứng là K phần tử đầu tiên trong dãy C. Ví dụ: KMIN.INP KMIN.OUT 446 3 1 4 2 4 3 5 4 5 2 5 3 4 5 Time limit: 1s Bài tập 6: BINLADEN Trùm khủng bố Bin Laden trốn trong 1 căn hầm được đào sâu xuống mặt đất M tầng, mỗi tầng có N phòng. Các phòng được ngăn cách bằng các cửa rất khó phá. Các phòng có cửa xuống phòng ngay phía dưới và 2 phòng ở 2 bên. Từ trên mặt đất có N cửa xuống N phòng tầng -1. Bin Laden ở tầng dưới cùng (tầng -M) phòng thứ N (phòng ở bên phải nhất). Mỗi cửa được làm bằng một kim loại khác nhau với độ dày khác nhau nên việc phá cửa cần thời gian khác nhau. Bạn hãy tìm cách đi từ mặt đất xuống phòng của Bin Laden nhanh nhất không hắn thoát mất. INPUT: BINLADEN.INP - Dòng 1 ghi M và N - Dòng 2 đến 2M + 1, dòng chẵn ghi N số, dòng lẻ ghi N - 1 số là chi phí để phá cửa. Chi phí của các cánh cửa thuộc [0, 1000]. OUTPUT: BINLADEN.OUT - Ghi ra 1 số là thời gian nhỏ nhất để đến được phòng của Bin Laden Ví dụ: BINLADEN.INP 42 99 10 1 10 99 1 99 10 1 10 99 1 BINLADEN.OUT 44 +--99--+--10--+ | | | | 1 | | | | +--10--+--99--+ | | | | 1 | | | | +--99--+--10--+ | | | | 1 | | | | +--10--+--99--+ | | | | 1 | 34 | | | +------+------+ Đi theo đường zigzac Tài liệu tham khảo 1. Nguồn bài tập: Thày Nguyễn Thanh Tùng, Thày Lê Minh Hoàng, Rumania OI, Poland OI, Russian OI, vn.spoj.pl. 2. Giải thuật và lập trình – T.S Lê Minh Hoàng – ĐHSP Hà Nội 3. Website: www.infoarena.ro 4. Test và solution các Thày cô có thể liên hệ với tác giả để download. 35 [...]... := 1; End; nheap := 0; End; {===============================} Procedure downheap(root : longint); Var child,u : longint; BEgin u := heap[ root]; repeat child := root*2; If (child cost [heap[ child+1]]) then inc(child); If (child >nheap) or (cost [heap[ child]]>= cost[u]) then break; heap[ root] := heap[ child]; pos [heap[ root]] := root; root := child; Until false; heap[ root]... Procedure upheap(child : longint); Var root,u : longint; Begin u := heap[ child]; 20 Repeat root := child div 2; If (root=0) or (cost [heap[ root]] h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* *} proceduredownheap(i : longint); var j : longint; 15 begin j := 2 * i; if j >nh then exit; if (j h[j+1]) then inc(j); if h[i] > h[j] then begin doicho(h[i],h[j]); downheap(j); end; end;... tồi lớn nhất và đặt lên giá, sau đó lấy món P[i] để lên sàn 3 Dễ dàng nhận thấy có thể sử dụng cấu trúc Heap để thực hiện thuật giải trong thời gian N.logK const tfi tfo type = = 'toycars.inp'; 'toycars.out'; arr1 arr2 = = array[0 1000000] of longint; array[0 100000] of boolean; var 23 fi,fo:text; n,k,p,res,nheap,x,dem,vc:longint; c,deg,d,a,pos,b,vt,next:arr1; free:arr2; { ... -*} procedureupheap(i : longint); begin if (i = 1) or (h[i] < h[i div 2]) then exit; if h[i div 2] < h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* -*} proceduredownheap(i : longint); var j : longint; begin j := 2 *i; if j >nh then exit; if (j ...CHUYÊN ĐỀ: CẤU TRÚC DỮ LIỆU HEAP Khái niệm Heap cấu trúc liệu đặc biệt quan trọng, giúp ta giải nhiều toán thời gian cho phép Độ phức tạp thông thường làm việc với Heap O(logN) Heap thực... LongInt); Begin Inc(nHeap); // Tăng số phần tử Heap Heap[nHeap] := x; // Thêm x vào Heap UpHeap(nHeap); End; Pop Rút phần tử vị trí v Heap: Gán Heap[ v] := Heap[ nHeap] tiến hành chỉnh lại Heap: Function... Begin Pop := Heap[ v]; // Lấy phần tử vị trí v khỏi Heap Heap[v] := Heap[ nHeap]; // Đưa phần tử cuối Heap vào vị trí v Dec(nHeap); // Giảm số phần tử Heap {Chỉnh lại Heap} UpHeap(v); DownHeap(v);

Ngày đăng: 14/10/2015, 14:02

TỪ KHÓA LIÊN QUAN

w