Dijkstra + 堆优化
来源:互联网 发布:jqueryeach遍历数组 编辑:程序博客网 时间:2024/05/17 14:20
Dijkstra算法原理请见:最短路径问题(Dijkstra解法)
该算法对于稠密图更加有效:
对于给出具有非负权重的边和源顶点S的图G,算法可在O(mlogn)时间内找出从s点到其他每一个顶点的距离。
如果图是稠密的,即对于某个ε>0,m>=n^(1+ε),可以被改善在O(m/ε)内执行。(m为图的边数,n为图的定点数)
最小堆模板:
- struct HeapElement {
- // key存储顶点序号,value存储到该顶点的最短距离
- int key, value;
- };
- struct MinHeap {
- HeapElement heap[MAXN];
- int position[MAXN];
- int size; // 顶点数
- void init() {
- heap[size=0].value = -INF;
- memset(position, 0, sizeof(position));
- }
- void insert(int key, int value) {
- heap[++size].key = key;
- heap[size].value = value;
- position[key] = size;
- siftUp(size);
- }
- void decrease(int index) {
- int x = heap[index].value;
- int y = heap[size].value;
- -- size;
- if (index == size+1)
- return;
- swap(heap[index], heap[size+1]);
- if (y >= x) {
- siftDown(index);
- } else {
- siftUp(index);
- }
- }
- int delmin() {
- int x = heap[1].key;
- decrease(1);
- return x;
- }
- void siftUp(int index) {
- while (index > 1) {
- if (heap[index].value < heap[index/2].value) {
- swap(heap[index],heap[index/2]);
- } else {
- break;
- }
- index /= 2;
- }
- }
- void siftDown(int index) {
- while (index*2 <= size) {
- index *= 2;
- if (index < size && heap[index].value > heap[index+1].value) {
- ++ index;
- }
- if (heap[index].value < heap[index/2].value) {
- swap(heap[index],heap[index/2]);
- } else {
- break;
- }
- }
- }
- void makeHeap() {
- for (int i = size/2; i > 0; -- i)
- siftDown(i);
- }
- void swap(HeapElement &a, HeapElement &b) {
- HeapElement temp = a;
- a = b;
- b = temp;
- int tmp = position[a.key];
- position[a.key] = position[b.key];
- position[b.key] = tmp;
- }
- }H;
代码实现:(hdu2544)
- #include <iostream>
- #define INF 0x7FFFFFFF
- using namespace std;
- const int SIZE = 105;
- int dist[SIZE];
- int G[SIZE][SIZE];
- bool vis[SIZE];
- struct HeapElement {
- int key, value;
- };
- void swap(HeapElement &ha, HeapElement &hb) {
- int key = ha.key;
- int value = ha.value;
- ha.key = hb.key;
- ha.value = hb.value;
- hb.key = key;
- hb.value = value;
- };
- // 使用邻接表储存图,线性表储存堆
- struct MinHeap {
- HeapElement heap[SIZE];
- int n; // 顶点数
- void makeheap() {
- for (int i = n/2; i > 0; -- i)
- siftDown(i);
- };
- void siftUp(int index) {
- int k = index;
- while (k > 1) {
- if (heap[k].value < heap[k/2].value) {
- swap(heap[k],heap[k/2]);
- } else {
- break;
- }
- k /= 2;
- }
- };
- void siftDown(int index) {
- int k = index;
- while (k*2 <= n) {
- k *= 2;
- if (k < n && heap[k].value > heap[k+1].value) {
- ++ k;
- }
- if (heap[k].value < heap[k/2].value) {
- swap(heap[k],heap[k/2]);
- } else {
- break;
- }
- }
- };
- void insert(HeapElement element) {
- heap[++n] = element;
- siftUp(n);
- };
- void decrease(int index) {
- int x = heap[index].value;
- int y = heap[n].value;
- n -= 1;
- // 若删除节点位于最末位置,则删除成功,无需其他操作。
- if (index == n+1)
- return;
- heap[index] = heap[n+1];
- if (y >= x) {
- siftDown(index);
- } else {
- siftUp(index);
- }
- };
- int decreaseMin() {
- int x = heap[1].key;
- decrease(1);
- return x;
- };
- }H;
- void dijkstra(int src, int n) {
- int i, j, w;
- bool flag;
- for (i = 1; i <= n; ++ i) {
- if (G[i][src] != INF) {
- dist[i] = G[src][i];
- HeapElement h = {i, dist[i]};
- H.insert(h);
- } else {
- dist[i] = INF;
- }
- }
- memset(vis, false, sizeof(vis));
- vis[src] = true;
- dist[src] = 0;
- for (i = 1; i < n; ++ i) {
- int node = H.decreaseMin();
- vis[node] = true;
- for (w = 1; w <= n; ++ w) {
- flag = false;
- if (!vis[w] && G[node][w] != INF) {
- if (dist[node] < dist[w] - G[node][w]) {
- dist[w] = dist[node] + G[node][w];
- }
- for (j = 1; j <= H.n; ++ j) {
- if (H.heap[j].key == w) {
- H.heap[j].value = dist[w];
- flag = true;
- break;
- }
- }
- if (!flag) {
- HeapElement h = {w, dist[w]};
- H.insert(h);
- } else {
- H.siftUp(j);
- }
- }
- }
- }
- };
- void init(int n) {
- for (int i = 1; i <= n; ++ i)
- for (int j = 1; j <= n; ++ j)
- G[i][j] = INF;
- H.n = 0;
- };
- int main()
- {
- int N, M, a, b, c;
- //freopen("C:\\Users\\Smile\\test.txt","r",stdin);
- //freopen("C:\\Users\\Smile\\out.txt", "w", stdout);
- while (scanf("%d%d",&N,&M)!=EOF, N&&M) {
- init(N);
- for (int i = 0; i < M; ++ i) {
- scanf("%d%d%d",&a,&b,&c);
- if (G[a][b] > c) {
- G[a][b] = c;
- G[b][a] = c;
- }
- }
- dijkstra(1, N);
- printf("%d\n",dist[N]);
- }
- }
0 0
- 堆优化的Dijkstra
- DIJKSTRA堆优化
- Dijkstra + 堆优化
- 堆优化Dijkstra模版
- Dijkstra+堆优化
- 堆优化Dijkstra
- 堆优化Dijkstra
- Dijkstra + 堆优化
- Dijkstra+堆优化 模板
- Dijkstra堆优化
- [ 模板 ] 堆优化Dijkstra
- 堆优化Dijkstra 模版
- Dijkstra + 堆优化
- Dijkstra+堆优化模板
- Dijkstra堆优化学习
- Heap+Dijkstra堆优化的Dijkstra
- hdu1874 Dijkstra(堆优化)+floyd
- 堆优化的Dijkstra算法
- HDU 1013 Digital Roots【水题】
- Android Matrix手势缩放自定义view 不止于Imageview
- redis test
- 关于在C/C++语言中,函数如何返回数组,数组如何作为参数传递以及返回数组的函数该如何调用问题的总结
- bzoj4584: [Apio2016]赛艇
- Dijkstra + 堆优化
- Spring学习总结(8)——25个经典的Spring面试问答
- spring boot 拦截器实现防重复提交
- 浙大 PAT Advanced level 1022. Digital Library (30)
- 学习Java有没有什么捷径
- Servlet Error
- Cocos2d-JS 性能优化
- 代写安卓app程序
- poj1325 machine schedule