码迷,mamicode.com
首页 > 其他好文 > 详细

BellmanFord的队列优化

时间:2017-11-19 22:12:31      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:个数   while   bellman   next   距离   无效   顶点   void   i++   

技术分享图片

当我们使用BellmanFord算法时可以了解到,当我们第一次遍历时松弛的边是从源点可以直接到达的边,接着再从这些顶点可以直接到达的边进行松弛,以此类推。
所以基于以上思想我们可以去除BellmanFord算法中的无效循环。

首先我们可以选择使用连个数组first和next,first用于记录每条边的第一条边(最后一次输入的边),next用于记录每条边的上一条边,如果没有上一条边则next为-1。再使用que数组(队列)存放已经松弛过的顶点,book数组用来记录顶点是否已经入队。首先,我们需要先把源点入队,且记录下源点已经入队。我们默认从源点到其他所有顶点的距离为999(无穷大)。我们从源点开始找出其第一条出边(1->5 10)接下来的判断就和BellmanFord中一样,松弛该边成功,顶点5入队。接着找出源点开始的第二条边(1->2 2),松弛成功,将2号顶点入队。此时我们发现从源点开始可以直接到达的顶点都没有了,然后我们把源点出队,从队列中的第二个顶点(5)开始向下搜索其可直接到达的边进行松弛,以此类推,直到队列中没有顶点为止。

int[] u = new int[7];
int[] v = new int[7];
int[] w = new int[7];

int[] first = new int[5];//顶点个数
int[] next = new int[7];//边的条数

int[] dis = new int[5];//原点到各个点之间的距离

int[] book = new int[5];

int head = 0;
int tail = 1;
int[] que = new int[20];



private void initArrs() {
    for (int i = 1; i <= 4; i++) {
        dis[i] = 999;
    }

    for (int i = 0; i <= 4; i++) {
        first[i] = -1;
    }

    u[0] = 0;
    v[0] = 1;
    w[0] = 2;

    u[1] = 0;
    v[1] = 4;
    w[1] = 10;

    u[2] = 1;
    v[2] = 2;
    w[2] = 3;

    u[3] = 1;
    v[3] = 4;
    w[3] = 7;

    u[4] = 2;
    v[4] = 3;
    w[4] = 4;

    u[5] = 3;
    v[5] = 4;
    w[5] = 5;

    u[6] = 4;
    v[6] = 3;
    w[6] = 6;

    for (int i = 0; i <= 6; i++) {
        next[i] = first[u[i]];
        first[u[i]] = i;
    }
}

@Test
public void testBellmanFordBetter() {
    initArrs();
    book[0] = 1;
    que[0] = 0;

    while (head < tail) {
        int k = first[que[head]];
        while (k != -1) {
            if (dis[v[k]] > dis[u[k]] + w[k]) {
                dis[v[k]] = dis[u[k]] + w[k];
                if (book[v[k]] == 0) {
                     que[tail++] = v[k];
                     book[v[k]] = 1;
                }
            }
            k = next[k];
        }
        book[que[head]] = 0;
        head++;
    }

    for (int i = 0; i <= 4; i++) {
        System.out.println(dis[i]);
    }
}

BellmanFord的队列优化

标签:个数   while   bellman   next   距离   无效   顶点   void   i++   

原文地址:http://www.cnblogs.com/javathinker/p/7862202.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!