zoukankan      html  css  js  c++  java
  • hud2544dijkstra+堆优化

    该算法对于稠密图更加有效:

    对于给出具有非负权重的边和源顶点S的图G,算法可在O(mlogn)时间内找出从s点到其他每一个顶点的距离。

    如果图是稠密的,即对于某个ε>0,m>=n^(1+ε),可以被改善在O(m/ε)内执行。(m为图的边数,n为图的定点数)

    最小堆模板:

    1 jfdkjfks
     1 struct HeapElement {
     2     // key存储顶点序号,value存储到该顶点的最短距离 
     3     int key, value;
     4 };
     5 struct MinHeap {
     6     HeapElement heap[MAXN];
     7     int position[MAXN];
     8     int size; // 顶点数
     9     void init() { 
    10         heap[size=0].value = -INF; 
    11         memset(position, 0, sizeof(position));
    12     }
    13     void insert(int key, int value) {
    14         heap[++size].key = key;
    15         heap[size].value = value;
    16         position[key] = size;
    17         siftUp(size);
    18     }
    19     void decrease(int index) {
    20         int x = heap[index].value;
    21         int y = heap[size].value;
    22         -- size;
    23         if (index == size+1)
    24             return;
    25         
    26         swap(heap[index], heap[size+1]);
    27         if (y >= x) {
    28             siftDown(index);    
    29         } else {
    30             siftUp(index);    
    31         }
    32     }
    33     int delmin() {
    34         int x = heap[1].key;
    35         decrease(1);
    36         return x;
    37     }
    38     void siftUp(int index) {
    39         while (index > 1) {
    40             if (heap[index].value < heap[index/2].value) {
    41                 swap(heap[index],heap[index/2]);    
    42             } else {
    43                 break;
    44             }
    45             index /= 2;
    46         }
    47     }
    48     void siftDown(int index) {
    49         while (index*2 <= size) {
    50             index *= 2;
    51             if (index < size && heap[index].value > heap[index+1].value) {
    52                 ++ index;
    53             }
    54             if (heap[index].value < heap[index/2].value) {
    55                 swap(heap[index],heap[index/2]);
    56             } else {
    57                 break;
    58             }
    59         }
    60     }
    61     void makeHeap() {
    62         for (int i = size/2; i > 0; -- i) 
    63             siftDown(i);
    64     }
    65     void swap(HeapElement &a, HeapElement &b) {
    66         HeapElement temp = a;
    67         a = b;
    68         b = temp;
    69         int tmp = position[a.key];
    70         position[a.key] = position[b.key];
    71         position[b.key] = tmp;
    72     }
    73 }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
    ",dist[N]);    
        }
    }
    

      

  • 相关阅读:
    用node.js解决编程题的输入问题
    css兼容篇
    关于Hogan的学习笔记
    javascript实现瀑布流
    代码管理工具之SVN简介
    原创•模板匹配实践之Opencv+Python识别PDB板图片
    sklearn 神经网络MLPclassifier参数详解
    (转)knn算法简单实例分享
    机器学习初识——KNN算法
    开发工具VScode实用插件推荐分享
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/5434518.html
Copyright © 2011-2022 走看看