亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

基于稀疏圖上的Johnson算法的詳解

2020-01-26 16:18:23
字體:
供稿:網(wǎng)友

算法步驟簡(jiǎn)述:

1.計(jì)算圖G加入新結(jié)點(diǎn)后的圖G',加入的新結(jié)點(diǎn)0到所有原結(jié)點(diǎn)之間距離為0,同時(shí)形成新的邊集E';

2.使用Bellman-Ford算法處理G',并形成0結(jié)點(diǎn)到各結(jié)點(diǎn)的最小距離d。

3.如果Bellman-Ford算法檢測(cè)出有負(fù)權(quán)回路則提示FALSE并退出,否則繼續(xù)。

4.對(duì)所有G'中的頂點(diǎn)v,根據(jù)0結(jié)點(diǎn)到v的最小距離,將h(v)設(shè)置為這個(gè)值。

5.對(duì)所有的邊w(u,v),權(quán)值更新為w(u,v)+h(u)-h(v)

6.對(duì)圖G中所有結(jié)點(diǎn)運(yùn)行Dijkstra算法計(jì)算與其他頂點(diǎn)最短距離d'[u][v]

(此處假定G和w集合是分開存儲(chǔ)的。直接使用G'也可以,因?yàn)?結(jié)點(diǎn)對(duì)其他結(jié)點(diǎn)是不可達(dá)的,但這顯然浪費(fèi)了計(jì)算時(shí)間。如果權(quán)值信息存在G'中,可以對(duì)G'進(jìn)行操作,只不過跳過了0結(jié)點(diǎn)的處理)

7.原圖G中最短距離d[u][v] = d'[u][v] +h(v)-h(u)

  代碼中有的地方?jīng)]有優(yōu)化,比如輔助結(jié)構(gòu)vassist其實(shí)在Bellman-Ford算法和Dijkstra算法兩個(gè)函數(shù)中用法稍微有所不同,而且成員變量在前者中只用了2個(gè);同時(shí)松弛算法relax也有類似的情況。前者是簡(jiǎn)單的復(fù)用,后者直接用名字區(qū)分。

  代碼包含三部分:Bellman-Ford算法、Dijkstra算法、用二項(xiàng)堆實(shí)現(xiàn)的優(yōu)先級(jí)數(shù)組(Dijkstra算法要用到)。以下是算法的C語言版本,測(cè)試實(shí)例同《算法導(dǎo)論》圖25-1

復(fù)制代碼 代碼如下:

#include <stdio.h>
#include <stdlib.h>

#define U    65535
#define PARENT(i)    ((i-1)/2)
#define LEFT(i)        (2*(i)+1)
#define RIGHT(i)    (2*(i)+2)
#define N 5

struct vertex {
    int key;
    struct vtable *adj;
};

struct vtable {
    int key;//這個(gè)key是在vertex數(shù)組的序號(hào)
    //struct vertext *v;
    int w;
    struct vtable *next;
};

struct vassist {
    int d;
    int p;
    int key;
};

 


int insert(struct vertex *,int,int,int,int);
int walk(struct vertex *,int,int);
struct vassist *initialize_ss(int,int);
int relaxd(int *,int ,int ,int);
int relaxb(struct vassist *,int ,int ,int);
int build_min_heap(struct vassist *,int);
int min_heapify(struct vassist *, int ,int);
int heap_extract_min(struct vassist *,int);
int inheap(struct vassist *,int ,int );
int heap_decrease(struct vassist *,int ,int);
int dijkstra(struct vertex *,int,int,int **);
int bellman_ford(struct vertex *,int*, int,int);

int insert(struct vertex *p,int len,int i,int j,int w) {
    struct vtable *q,*prev;
    q = p[i].adj;
    printf("key:%d/n",p[i].key);
    prev = NULL;
    while(q!=NULL) {
        if (q->key == j) {
            printf("error: v %d to %d already exist./n",i,j);
            return 0;
        }
        else {
            prev = q;
            q=q->next;
        }
    }
    q = (struct vtable*)malloc(sizeof(struct vtable));
    q->key = j;
    q->w = w;
    q->next = NULL;
    if(prev!=NULL)
        prev->next = q;
    else
        p[i].adj = q;
    return 1;
}

int walk(struct vertex *p,int len,int i) {
    struct vtable *q = p[i].adj;   
    while(q!=NULL) {
        printf(" %d,w is %d/n",q->key,q->w);
        q=q->next;
    }
    printf("/n");
}

struct vassist *initialize_ss(int size,int s) {
    int i;
    struct vassist *va;
    va = (struct vassist *)malloc(size*sizeof(struct vassist));
    for(i=0;i<size;i++) {
        va[i].key = i;//建堆后i!=key
        va[i].d = U;
        va[i].p = -1;
    }
    va[s].d = 0;
    return va;
}

//relax for dijkstra
int relaxd(int *p,int u,int v,int w) {//w=w(u,v)
    if(p[v]>p[u]+w) {
        p[v] = p[u]+w;
        //為了簡(jiǎn)單處理,p使用的是數(shù)組
        //沒有父母標(biāo)記
        //如果想用父母標(biāo)記,請(qǐng)將p改為一個(gè)自定義的結(jié)構(gòu)體
    }
    return 1;
}

//relax for beltman_ford
int relaxb(struct vassist *va,int u,int v,int w) {//w=w(u,v)
    if(va[v].d>va[u].d+w) {
        va[v].d = va[u].d+w;
        va[v].p = u;
    }
    return 1;
}


int bellman_ford(struct vertex *graph,int *h,int size,int s) {//算法要求不含源點(diǎn)可達(dá)的負(fù)權(quán)回路
    int i,j;
    struct vtable *p;
    struct vassist *va;
    va = initialize_ss(size,s);
    for(i=1;i<size;i++)
        for(j=0;j<size-1;j++) {
            p = graph[j].adj;
            while(p!=NULL) {
                relaxb(va,j,p->key,p->w);
                p=p->next;
            }
        }

    printf("from %d,/n",s);
    for(j=0;j<size;j++)
        printf("to %d: %d/n",j,va[j].d);
       

    for(j=0;j<size;j++) {//對(duì)0結(jié)點(diǎn)不必要
        p = graph[j].adj;
        while(p!=NULL) {
            if(va[p->key].d>va[j].d+p->w)
                return 0;
            p = p->next;
        }
    }
    for(j=1;j<=size;j++)
        h[j] = va[j].d;
    free(va);
    h[0] = 0;
    return 1;
}

int build_min_heap(struct vassist *va,int size) {//建堆
    int i;
    for (i =size/2-1; i>=0; i--)
        min_heapify(va,i,size);

    return 1;
}


int min_heapify(struct vassist *va, int i,int heap_size) {
    int l,r,min;
    struct vassist temp;
    int tmin = U;
    l = LEFT(i);
    r = RIGHT(i);
    if ((l < heap_size) &&(va[l].d<va[i].d)) {
        min = l;
        tmin = va[l].d;
    }
    else {
        min = i;
        tmin = va[i].d;
    }
    if ((r < heap_size) &&(va[r].d<va[min].d)) {
        min = r;
        tmin = va[r].d;
    }
    if (!(min == i)) {
        temp.d = va[min].d;
        temp.p = va[min].p;
        temp.key = va[min].key;

        va[min].d = va[i].d;
        va[min].p = va[i].p;
        va[min].key = va[i].key;

        va[i].d = temp.d;
        va[i].p = temp.p;
        va[i].key = temp.key;

        min_heapify(va,min,heap_size);
    }
    return 1;
}

int heap_extract_min(struct vassist *va,int heap_size) {
    int min;   
    if ( heap_size<1 )
        return -1;
    min = va[0].key;
    va[0].p = va[heap_size -1].p;
    va[0].d = va[heap_size -1].d;
    va[0].key = va[heap_size -1].key;
    heap_size = heap_size -1;
    min_heapify(va,0,heap_size);
    return min;
}

int inheap(struct vassist *va,int heap_size,int j) {
    int i;
    for(i=0;i<heap_size;i++)
        if(va[i].key == j)
            return i;
    return -1;
}

int heap_decrease(struct vassist *va,int i,int key_new) {
    struct vassist temp;   
    if(key_new>va[i].d)
        return 0;
    va[i].d = key_new;
    while((i>0)&&(va[PARENT(i)].d > va[i].d)) {
        temp.d = va[i].d;
        temp.p = va[i].p;
        temp.key = va[i].key;
        va[i].d = va[PARENT(i)].d;
        va[i].p = va[PARENT(i)].p;
        va[i].key = va[PARENT(i)].key;
        va[PARENT(i)].d = temp.d;
        va[PARENT(i)].p = temp.p;
        va[PARENT(i)].key = temp.key;
        i = PARENT(i);
    }
    return 1;       
}

int dijkstra(struct vertex *graph,int len,int s,int **delta) {
    int i,j,heap_size;
    struct vtable *q;
    struct vassist *va;
    int *p;
    p = (int *)malloc(len * sizeof(int));
    for(i=0;i<len;i++)
        p[i] = U;
    p[s] = 0;
    heap_size = len;

    va = initialize_ss(len,s);
    build_min_heap(va,heap_size);//va被拿去建堆,后續(xù)輸出距離時(shí)不能再用了


    while(heap_size>0) {
        i = heap_extract_min(va,heap_size);
        printf("node:%d/n",i);
        heap_size--;
        for(j=0;j<heap_size;j++)
            printf("key:%d,d:%d, in array:%d/n",va[j].key,va[j].d,p[va[j].key]);
        q = graph[i].adj;
        while(q!=NULL) {
            j=inheap(va,heap_size,q->key);
            if(j>=0)
                if(va[j].d>p[i]+q->w)   
                    heap_decrease(va,j,p[i]+q->w);
            relaxd(p,i,q->key,q->w);//其實(shí)可以合并heap_decreas和relax,不過為了接口簡(jiǎn)單沒有這樣做
            printf("relax %d to %d ,w is %d/n",i,q->key,q->w);
            q = q->next;
        }
        for(j=0;j<heap_size;j++)
            printf("key:%d,d:%d, in array:%d/n",va[j].key,va[j].d,p[va[j].key]);
    }
    for(i=0;i<len;i++)
        printf("from %d to %d, distance is %d/n",s,i,p[i]);

    free(va);

    for(i=0;i<len;i++) {
        delta[s][i] = p[i];
    }
    free(p);   

}

int **johnson(struct vertex *g, int n) {
    int i,j;
    int *h,**delta,**d;
    struct vertex *gn;
    struct vtable *p;
    gn = (struct vertex *)malloc(n*sizeof(struct vertex));
    h = (int *)malloc(n*sizeof(int));
    delta = (int**)malloc(n*sizeof(int *));
    d = (int**)malloc(n*sizeof(int *));
    for(i=0;i<n;i++) {
        delta[i]=(int*)malloc(n*sizeof(int));
        d[i]=(int*)malloc(n*sizeof(int));
    }
    for(i=0;i<n;i++)
        gn[i] = g[i];

    for(i=1;i<n;i++)
            insert(gn,n,0,i,0);
    if(!bellman_ford(gn,h,n,0)) {
        printf("the input graph contains a negative-weight cycle./n");
        return NULL;
    }

    for(i=0;i<n;i++) {
        p = gn[i].adj;
        while(p!=NULL) {
            p->w = p->w+h[i]-h[p->key];
            p=p->next;
        }
    }
    for(i=0;i<n;i++)
        walk(gn,n,i);

    printf("before dijkstra/n");
    for(i=1;i<n;i++) {
        dijkstra(gn,n,i,delta);
        for(j=1;j<n;j++)
            d[i][j] = delta[i][j] + h[j] - h[i];

    }
    for(i=1;i<n;i++) {
        for(j=1;j<n;j++)
            printf("%d/t",d[i][j]);
        printf("/n");
    }
    return d;
}

int main(){
    int i,j;
    int **d;
    struct vertex vt[N+1];//為0結(jié)點(diǎn)的加入預(yù)留位置
    for(i=0;i<N+1;i++) {
        vt[i].adj = NULL;
        vt[i].key = i;
    }

    insert(vt,N+1,1,2,3);
    insert(vt,N+1,1,3,8);
    insert(vt,N+1,1,5,-4);
    insert(vt,N+1,2,4,1);
    insert(vt,N+1,2,5,7);
    insert(vt,N+1,3,2,4);
    insert(vt,N+1,4,3,-5);
    insert(vt,N+1,4,1,2);
    insert(vt,N+1,5,4,6);
    d = johnson(vt,N+1);

    return 1;
}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

一区二区三区精品99久久| 高清全集视频免费在线| 国产精品久久久久高潮| 成人久久一区二区三区| 91免费视频国产| 亚洲午夜日本在线观看| 日韩精彩视频在线观看| 波多野结衣在线一区二区| 久精品国产欧美| 波多野结衣精品| 国内精品视频一区二区三区| 99xxxx成人网| 亚洲不卡一卡2卡三卡4卡5卡精品| 午夜精品久久久久久久蜜桃app| 国产成人精品亚洲日本在线观看| 国产精品麻豆免费版现看视频| 欧美一区二区视频免费观看| 久久午夜色播影院免费高清| 国产精品二区一区二区aⅴ污介绍| 少妇高潮爽到全身痉挛抽搐| 色综合久久久久久久久五月| www国产在线| 欧美日韩国产美女| h文在线观看免费| 精品欧美一区二区久久| 一个人看的www免费观看视频| 久草在线视频资源| 欧美mv和日韩mv的网站| theporn国产在线精品| 久热中文字幕| 在线中文字幕一区| 麻豆视频在线观看| 欧洲中文在线| 久久精品一区二| 精品无人区一区二区三区| 欧美一级高清片| 日韩在线国产精品| 成人午夜在线观看视频| 黄色av一区二区三区| 欧美午夜电影一区二区三区| 成人av影音| 香蕉视频免费在线播放| 欧美mv日韩mv亚洲| 神马影院午夜我不卡影院| 欧美色爱综合| 91色琪琪电影亚洲精品久久| 国产激情久久久久| 不卡av电影院| 国产ts变态重口人妖hd| 久久久久久久久久久久久久久久久久久久| 国产欧美日韩一区二区三区在线观看| 久久久久免费看| 先锋av资源| 欧美怡红院视频| 欧美日韩免费做爰视频| 亚洲午夜久久久久久久久电影院| 91在线精品一区二区| 38少妇精品导航| 久久在线免费观看视频| 欧美精品a∨在线观看不卡| 九九视频这里只有精品| 少妇太紧太爽又黄又硬又爽| 亚洲精品视频在线观看免费| 精品久久久久久久久久久久| 日本免费高清不卡| 欧美日韩播放| 国产麻豆免费观看| 亚洲小视频在线观看| 91资源在线视频| 97在线观看免费高清视频| 自拍亚洲欧美老师丝袜| 国产精品suv一区| 6080yy精品一区二区三区| 久久激情综合网| 中文字幕无人区二| 18成人在线视频| 懂色av一区二区三区在线播放| 中文字幕这里只有精品| 亚洲图片有声小说| 亚洲国产成人精品久久| 91在线视频播放地址| 欧美人妖在线| 国产精品的网站| 精品伊人久久大线蕉色首页| 欧美性资源免费| 色av吧综合网| 午夜精品免费观看| 日韩一级片av| 精产国品一二三区| 成人全视频免费观看在线看| 亚洲国产精品无码久久久久高潮| 欧美一级片在线观看| 国产精品www在线观看| 欧美成年人在线观看| 96国产粉嫩美女| theporn国产精品| 91精品久久久久久久| 亚洲人av在线| 久久成人综合| 日韩欧美一区二区三区免费观看| 欧美性感一区二区三区| 国产精品网站在线播放| 午夜影院在线播放| 最近中文字幕免费在线观看| 欧美福利视频导航| 五月色婷婷综合| 97品白浆高清久久久久久| 黄色短视频在线观看| 欧美日韩二三区| 欧美网色网址| 精品少妇一区二区三区密爱| h狠狠躁死你h高h| 精品日产免费二区日产免费二区| 伊人久久久久久久久久| 国产一区免费观看| 国产精品久久久久影视| 亚洲电影第三页| heyzo高清中文字幕在线| av在线网站观看| 日韩在线xxx| 欧美亚洲动漫另类| 日本黄xxxxxxxxx100| 美国十次了思思久久精品导航| 人妖精品videosex性欧美| 国产男女无套免费网站| 亚洲国产精品一区二区第四页av| 国产精品久久电影观看| 亚洲一区中文字幕在线| 伊人久久大香线蕉综合影院首页| 特大黑人巨人吊xxxx| 亚洲加勒比久久88色综合| 欧美美乳视频网站在线观看| 久久久夜精品| 欧美 日本 国产| 91麻豆精品91久久久久久清纯| 亚洲成人直播| 天天躁日日躁aaaa视频| 99re6在线视频精品免费| 亚洲国产精品激情在线观看| 精品香蕉一区二区三区| 亚洲第五色综合网| 亚洲中字黄色| 中文字幕91视频| 久久久精品国产亚洲| 日本五码在线| 欧洲成人在线观看| lutube成人福利在线观看| 熟女少妇内射日韩亚洲| 51久久精品夜色国产麻豆| 久久av高潮av无码av喷吹| 久久伦理在线| 在线观看国产成人| 亚洲电影在线免费观看| 97在线视频免费观看完整版| 欧美成人激情免费网| 国产成人精品一区二区免费看京| 久久综合成人| 国产精品一区三区| 国产精品永久在线| 欧美电影免费观看| 久热中文字幕| 国产一区免费在线观看| www.av网站| 成人午夜视频免费在线观看| 曰本人一级毛片免费完整视频| 中文字幕桃花岛| 国产盗摄——sm在线视频| 欧美成年网站| 青青草国产精品97视觉盛宴| 国产porn在线| 中文在线观看免费视频| 男人和女人做事情在线视频网站免费观看| 意大利激情丛林无删减版dvd| www.com操| 九七电影院97理论片久久tvb| 国产鲁鲁视频在线观看免费| 亚洲欧美自拍偷拍色图| 久久久久国产精品| 国产视频二区| 成人黄色大片在线免费观看| 国产精品天天操| 神马久久一区二区三区| 成人精品aaaa网站| www黄com| 国产性xxxx18免费观看视频| 懂色av一区二区| 高清欧美电影在线| 精品一区二区三孕妇视频| 中文在线一区二区| 日韩区国产区| 免费观看在线综合色| 亚洲欧美日韩国产成人精品影院| 高清免费日韩| 韩国精品一区二区三区| 国产系列精品av| av一区二区在线播放| 在线观看h视频| 人体久久天天| 亚洲91精品在线| 日本免费黄视频| 免费99热在线观看| 在线播放一区二区精品产| 少妇熟女一区二区| 亚洲综合色区另类av| 麻豆视频免费在线播放| 国产欧亚日韩视频| 95精品视频在线| 国产精品69一区二区三区| 日b视频免费观看| 五月婷婷在线观看| 亚洲制服一区| 狠狠鲁狠狠操| 国产精品三级久久久久久电影| 日韩在线一区二区三区| 午夜av噜噜噜噜噜噜| 91人妻一区二区三区蜜臀| 欧美老头gaygay1069| 后入内射无码人妻一区| 国产色播av在线| 免费观看日韩毛片| 国产欧美一区二区三区在线看蜜臀| 91精品国产综合久久久久久蜜臀| 不卡的电视剧免费网站有什么| 日韩成人黄色| 成人在线中文| 中文在线资源观看网站视频免费不卡| 精品人妻一区二区三区含羞草| 5566中文字幕一区二区电影| 国产网友自拍视频导航网站在线观看| 精品日产免费二区日产免费二区| 久久超碰亚洲| 亚洲国产综合人成综合网站| 亚洲免费一级视频| 日本不卡免费高清视频| 五月天激情综合| 国产精选一区二区三区不卡催乳| 久久人人99| 日本熟女一区二区| 日本强好片久久久久久aaa| а√中文在线资源库| 黑人巨大精品欧美一区二区一视频| 99自拍视频在线| 久久高清内射无套| 91久久久久久久久| 日本aa大片在线播放免费看| 国产精品一区二区在线免费观看| www视频在线观看免费| 美国一级片在线免费观看视频| 国产亚洲一本大道中文在线| 一本一生久久a久久精品综合蜜| 性高潮久久久久久| 亚洲欧洲精品在线| 欧美日韩调教| 国产午夜精品视频一区二区三区| 性欧美长视频免费观看不卡| 亚州av一区| 91视频在线免费| 一个人看的免费网站www视频| 欧美理论在线| 99久久精品日本一区二区免费| 中文字幕欧美日韩va免费视频| 欧美二区视频| 国产av麻豆mag剧集| 一区二区成人在线观看| 国产精品国产精品国产专区不片| 免费一级淫片aaa片毛片a级| 欧美中文一区| 啦啦啦中文高清在线视频| 亚洲超碰精品一区二区| 欧美精品三级在线观看| 国产男小鲜肉同志免费| 亚洲黄色小视频| 精品国产精品国产精品| 性欧美超级视频| 国产精品三级| 精品国产人妻一区二区三区| 亚洲xxx自由成熟| 91福利在线视频| 久久精品99久久久香蕉| 成人av网址在线观看| 99精品国产在热久久| 国新精品乱码一区二区三区18| 国产成人香蕉在线视频网站| 国产呦系列欧美呦日韩呦| 小舞被吸乳羞羞网站视频| 美女三级福利视频| 亚洲国产女人aaa毛片在线| 欧美日韩精品系列| 欧美熟妇精品一区二区| 136福利第一导航国产在线| 成人一区二区av| 国产精品一区一区三区| 亚洲熟妇无码av| 国产精品二区三区四区| 91动漫在线看| 2021亚洲天堂| 四虎精品一区二区永久在线观看| 欧美日韩性生活| 国产精品白丝在线| 中文字幕第一页在线| 日韩av一区二区三区在线| 97中文字幕在线观看| 国产91丝袜在线播放| 国产制服丝袜一区| 亚洲精品一区二区三区区别| 欧洲美女7788成人免费视频| 艳女tv在线观看国产一区| 久久成人资源| 国产欧美日韩免费看aⅴ视频| 日本一本草久p| 日韩中文字幕不卡视频| 亚洲国产无线乱码在线观看| 成人av在线播放网址| 欧美顶级少妇做爰| 国产综合无码一区二区色蜜蜜| 中文字幕在线不卡| 国内精品久久久久久久影视麻豆| 成人欧美一区二区三区1314| 九色91porny| 亚洲女同ⅹxx女同tv| 亚洲综合网在线观看| www日本在线观看| 精品人妻无码一区二区性色| а√天堂中文在线资源8| 91人人爽人人爽人人精88v| 丰满熟女人妻一区二区三区| 亚洲成av人片在线观看无| 男女精品网站|