优先队列:
优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。
1.头文件&定义
#include <queue>
#include <functional> //greater<>// 定义
priority_queue<int> pq;
2.默认优先输出大数据
priority_queue<Type, Container, Functional>
其中, Type 为数据类型. Container 为保存数据的容器. Functional 为元素比较的方式.
若不写后面两个参数.
容器 默认使用 vector
比较方式 默认使用 operator < 即优先队列是大顶堆. 队头元素最大
srand(time(NULL));
priority_queue<int> pq1; // 默认是最大堆...
std::cout << "start..." << endl;
for (int i = 0; i < 10; i++) {int t = rand() % 100;cout << t << ends;pq1.push(t);
}
std::cout << endl;
while (!pq1.empty())
{cout << pq1.top() << ends;pq1.pop();
}
cout << endl;
3.优先输出小数据 即小顶堆
priority_queue<int, vector<int>, greater<int> > p;
使用
greater<int>
. 即改用operator >
小根堆声明方式
大根堆是把大的元素放堆顶,小根堆就是把小的元素放到堆顶。
priority_queue<int, vector<int>, greater<int>> pq2; // 最小堆std::cout << "start..." << endl;
for (int i = 0; i < 10; i++) {int t = rand() % 100;std::cout << t << ends;pq2.push(t);
}
std::cout << endl;while (!pq2.empty())
{cout << pq2.top() << ends;pq2.pop();
}
cout << endl;
#include<iostream>
#include<queue>
#include<functional>
using namespace std;
using ll = long long;
ll v[10001000], l[1000010], r[1000010];//l记录左边坐标,r记录右边坐标
void Delet(int i)//删除该点
{r[l[i]] = r[i], l[r[i]] = l[i];//该点的右边的点的下标赋给该点左边点记录右边点下标的值,同理左边v[l[i]] += v[i], v[r[i]] += v[i];//该点加给左右两边的点
}
int main()
{int n, k;cin >> n >> k;priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> h;//最小堆r[0] = 1, l[n + 1] = n;for (int i = 1; i <= n; i++){cin >> v[i];l[i] = i - 1, r[i] = i + 1;//记录该点的左右坐标h.push({ v[i],i });//权值和下标}while (k--){pair<ll, int> p = h.top();h.pop();//取队首if (p.first != v[p.second])//v会更新,需要重新放入堆{h.push({ v[p.second],p.second });k++;}else//删除该点Delet(p.second);}int head = r[0];//从右到左输出while (head != n + 1){cout << v[head] << " ";head = r[head];}
}