zoukankan      html  css  js  c++  java
  • dij+heap

    学了一下dij+heap

    用它做了做HDU2544

    遇到了两个问题:

    1.堆数组H开的太小会RE

    2.对于该题跑时15ms, 不加优化15ms,spfa跑时0ms

    探究:

    1.对于第一个问题:结点是会被重复加入的。因为每次松弛时,都会有结点加入堆,因此加入堆的结点总数会大于总的结点数。

    2.对于第二个问题,在网上找了找资料,迷茫中闪现一丝曙光。资料地址:http://blog.csdn.net/lyso1/article/details/5687180

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAXN 106
    #define INF (1<<20)
    
    int d[MAXN], w[MAXN][MAXN];
    unsigned char vis[MAXN];
    
    int cmp(int i, int j){
        return d[i]>d[j];
    }
    
    void swap(int A[], int i, int j){
        int t = A[i];
        A[i] = A[j];
        A[j] = t;
    }
    
    void Heap_init(int A[]){
        A[0] = 0;
    }
    
    int heap_empty(int A[]){
        return A[0] == 0;
    }
    
    void heap_insert(int A[], int x){
        int i = ++A[0];
        A[A[0]] = x;
    
        while(i != 1){
            if(!cmp(A[i], A[i/2])) swap(A, i, i/2);
            else break;
    
            i /= 2;
        }
    }
    
    int delete_min(int A[]){
        int x = A[1], y = A[A[0]], i = 1;
        A[0]--;
        if(A[0] >= 1){
            A[1] = y;
            while((i*=2) <= A[0]){
                if(i+1<=A[0] && !cmp(A[i+1],A[i])) i++;
    
                if(cmp(A[i/2], A[i])) swap(A, i/2, i);
                else break;
            }
        }
        return x;
    }
    
    void Dijkstra(int v0, int n){
        int H[2000], i, y;
        Heap_init(H);
    
        for(i=0; i<n; i++){d[i] = INF; vis[i] = 0;}
    
        d[v0]=0;
        heap_insert(H, v0);
    
        while(!heap_empty(H)){
            int x;
            x = delete_min(H);
            if(!vis[x]){
                vis[x] = 1;
                for(y=0; y<n; y++){
                    if(d[y] > d[x] + w[x][y]){
                        d[y] = d[x] + w[x][y];
                        heap_insert(H, y);
                    }
                }
            }
         }
     }
    
    int main(){
        int n, m, a, b, c, i, j;
    
        while(scanf("%d %d", &n, &m) == 2 && (n != 0 || m != 0)){
            for(i=0; i<n; i++){
                for(j=0; j<n; j++)
                    w[i][j] = INF;
            }
            for(i=0; i<m; i++){
                scanf("%d %d %d", &a, &b, &c);
                w[a-1][b-1] = w[b-1][a-1] = c;
            }
    
            Dijkstra(0, n);
            printf("%d\n", d[n-1]);
        }
        return 0;
    }
  • 相关阅读:
    解决UITableView中Cell重用机制导致内容出错的方法总结
    Hdu 1052 Tian Ji -- The Horse Racing
    Hdu 1009 FatMouse' Trade
    hdu 2037 今年暑假不AC
    hdu 1559 最大子矩阵
    hdu 1004 Let the Balloon Rise
    Hdu 1214 圆桌会议
    Hdu 1081 To The Max
    Hdu 2845 Beans
    Hdu 2955 Robberies 0/1背包
  • 原文地址:https://www.cnblogs.com/tanhehe/p/2955795.html
Copyright © 2011-2022 走看看