优先队列
Feature
Priority queue is based on the ADT heap. And heap has its unique advantange about maintaining the property with its property in \(\Theta(\log (n))\). \(n\) represents the number of the elements.
Heap
Complete Binary Tree
Every leaf node has the same depth and every inner node has two children, this kind of tree is called complete binary tree. And if the lowest leaf nodes are gathered at the left side, and the difference between every pairs of the leaf nodes is no more than 1, it's called approximate complete binary tree.
Binary Heap
If every parent nodes' value is greater or smaller than all it's descendant nodes, this
complete binary tree is called binary heap.
Property
- \(index(parent)= \lfloor \frac{i}{2}\rfloor\). We can use \(i>>1\) to make this more efficient.
- \(index(leftchild)= 2\times i\). Code: \(i<<1\).
- \(index(rightchild)= 2\times i+1\). Code: \((i<<1)+1\)
- For any heap that contains \(n\) nodes, the number of nodes with height \(h\) is no bigger than \(\lceil \frac{n}{2^{h+1}} \rceil\)
- There are \(n-\lfloor \frac{n}{2}\rfloor\) leave nodes.
Important Operation
inline int Dad(int x)
{
return x>>1;
}
inline int Lft(int x)
{
return x<<1;
}
inline int Rit(int x)
{
return (x<<1)+1;
}
void MaxHeapify(ElementType *A, int i, int sz)
{
int l, r, nxt;
l= Lft(i);
r= Rit(i);
nxt= i;
if (l<= sz && A[i] < A[l]){
nxt= l;
}
if (r<= sz && A[nxt] < A[r]){
nxt= r;
}
if (nxt!= i){
swap(A[i], A[nxt]);
MaxHeapify(A, nxt, sz);
}
}
void BuildMaxHeap(ElementType *A, int &sz, int lth)
{
sz= lth;
int i= sz>>1;
while (i> 0){
MaxHeapify(A, i, sz);
}
}
ElementType HeapTop(ElementType *A)
{
return A[1];
}
ElementType HeapExtract(ElementType *A, int &sz)
{
if (sz< 1){
exit(1);
}
ElementType ans= A[1];
swap(A[1], A[sz]);
sz-= 1;
MaxHeapify(A, 1, sz);;
return ans;
}
void IncreaseKey(ElementType *A, int idx, ElementType key)
{
if (key< A[idx]){
exit(1);
}
A[idx]= key;
while (idx>1 && A[Dad(idx)]< A[idx]){
swap(A[Dad(idx)], A[idx]);
idx= Dad(idx);
}
}
void HeapInsert(ElementType *A, ElementType &NewElement, int &sz)
{
sz+= 1;
A[sz]= NewElement;
int i= sz;
while (i>1 && A[Dad(i)]< A[i]){
swap(A[Dad(i)], A[i]);
i= Dad(i);
}
}
OJ Practise
POJ 2021
Code With Plenty Of STL
#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
#include <map>
#include <stack>
using namespace std;
const int maxx= 100+5;
string ted("Ted");
struct dst
{
string name;
dst *fa;
int oag;
bool sured;
bool operator < (const dst& a) const{
return oag> a.oag || (oag== a.oag && name > a.name);
}
};
int SureAge(dst *tdr)
{
if (tdr->sured || ted== tdr->name){
return tdr->oag;
}
tdr->sured= true;
tdr->oag+= SureAge(tdr->fa);
return tdr->oag;
}
int main()
{
int n, i, x;
scanf("%d", &n);
for (i= 1; i<n+1; ++i){
scanf("%d", &x);
string fa, sn;
priority_queue<dst> fmy;
map<string, dst> fm;
int ag;
for (int j= 0; j< x; ++j){
cin>>fa>>sn>>ag;
if (fm.find(fa)== fm.end()){
fm[fa].name= fa;
fm[fa].oag= 0;
fm[fa].sured= false;
}
if (fm.find(sn)== fm.end()){
fm[sn].name= sn;
fm[sn].sured= false;
}
fm[sn].fa= &(fm[fa]);
fm[sn].oag= ag;
}
for (map<string, dst>::iterator iter= fm.begin(); fm.end()!= iter; ++iter){
SureAge(&(iter->second));
fmy.push(iter->second);
}
printf("DATASET %d\n", i);
fmy.pop();
for (int j= 0; j< x; ++j){
dst ans= fmy.top();
cout<< ans.name <<" "<< 100-ans.oag<<endl;
fmy.pop();
}
}
return 0;
}
Another version with the important implementation details about the heap operation.
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <stack>
#include <algorithm>
using namespace std;
const int maxx= 100+5;
string ted("Ted");
struct dst
{
string name;
dst *fa;
int oag;
bool sured;
bool operator < (const dst& a) const{
return oag> a.oag || (oag== a.oag && name > a.name);
}
};
int SureAge(dst *tdr)
{
if (tdr->sured || ted== tdr->name){
return tdr->oag;
}
tdr->sured= true;
tdr->oag+= SureAge(tdr->fa);
return tdr->oag;
}
inline int Dad(int x)
{
return x>>1;
}
inline int Lft(int x)
{
return x<<1;
}
inline int Rit(int x)
{
return (x<<1)+1;
}
void MaxHeapify(dst *fmy, int i, int sz)
{
int l, r, nxt;
l= Lft(i);
r= Rit(i);
nxt= i;
if (l<= sz && fmy[i] < fmy[l]){
nxt= l;
}
if (r<= sz && fmy[nxt] < fmy[r]){
nxt= r;
}
if (nxt!= i){
swap(fmy[i], fmy[nxt]);
MaxHeapify(fmy, nxt, sz);
}
}
dst HeapTop(dst *fmy)
{
return fmy[1];
}
dst HeapExtract(dst *fmy, int &sz)
{
if (sz< 1){
exit(1);
}
dst ans= fmy[1];
swap(fmy[1], fmy[sz]);
sz-= 1;
MaxHeapify(fmy, 1, sz);;
return ans;
}
void HeapInsert(dst *fmy, dst &dtr, int &sz)
{
sz+= 1;
fmy[sz]= dtr;
int i= sz;
while (i>1 && fmy[Dad(i)]< fmy[i]){
swap(fmy[Dad(i)], fmy[i]);
i= Dad(i);
}
}
int main()
{
int n, i, x;
scanf("%d", &n);
for (i= 1; i<n+1; ++i){
scanf("%d", &x);
string fa, sn;
dst fmy[maxx];
map<string, dst> fm;
int ag, sz= 0;
for (int j= 0; j< x; ++j){
cin>>fa>>sn>>ag;
if (fm.find(fa)== fm.end()){
fm[fa].name= fa;
fm[fa].oag= 0;
fm[fa].sured= false;
}
if (fm.find(sn)== fm.end()){
fm[sn].name= sn;
fm[sn].sured= false;
}
fm[sn].fa= &(fm[fa]);
fm[sn].oag= ag;
}
for (map<string, dst>::iterator iter= fm.begin(); fm.end()!= iter; ++iter){
SureAge(&(iter->second));
HeapInsert(fmy, iter->second, sz);
}
printf("DATASET %d\n", i);
HeapExtract(fmy, sz);
for (int j= 0; j< x; ++j){
dst ans= HeapExtract(fmy, sz);
cout<< ans.name <<" "<< 100-ans.oag<<endl;
}
}
return 0;
}
POJ 2431
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <utility>
#include <cstring>
using namespace std;
const int maxp= 1e6;
pair<int, int> ol[maxp];
priority_queue<int> tk;
bool cmp(pair<int, int> a, pair<int, int> b)
{
return a.first < b.first;
}
void Solve(int n, int p)
{
int pos= 0, ans= 0;;
for (int i= 0; i< n+1; ++i){
p-= ol[i].first- pos;
while ( p< 0){
if (tk.empty()){
cout<<-1;
return;
}
p+= tk.top();
tk.pop();
++ans;
}
pos= ol[i].first;
tk.push(ol[i].second);
}
cout<<ans;
}
int main()
{
int n, l, p;
scanf("%d", &n);
for (int i= 0; i< n; ++i){
scanf("%d %d", &(ol[i].first), &(ol[i].second));
}
scanf("%d %d", &l, &p);
for (int i= 0; i< n; ++i){
ol[i].first= l- ol[i].first;
}
sort(ol, ol+n, cmp);
ol[n]= pair<int, int>(l, 0);
Solve(n, p);
return 0;
}

浙公网安备 33010602011771号