• Bellman_Ford算法


          Bellman_Ford算法和Dijkstra算法都可以用来求解有向图的单源最短路径问题,但是,相比于Dijkstra算法, Bellman_Ford算法允许边的权重为负值。

        算法的详细讨论见算法导论或者下面这个博客http://blog.csdn.net/niushuai666/article/details/6791765

      代码如下:

    #include<iostream>
    
    using namespace std;
    
    #define Inf 65535
    #define NotAVerter -1
    
    /////////////////////邻接链表的相关定义//////////////////////
    typedef struct EdgeNode *position;
    typedef struct Led_table* Table;
    
    
    struct EdgeNode     //边表结点
    {
    	int adjvex;    // 邻接点域,存储该顶点对应的下标
    	int weight;     // 对应边的权值
    	int dis;     //此数据记录从源点到该节点的最短距离
    	int precursor;  //此数据记录该节点在广度优先树种的前驱节点
    	position next; // 链域,指向下一个邻接点
    };
    
    struct Led_table       // 邻接表结构
    {
    	int data;                //邻接表的大小
    	position *firstedge;       //边表头指针,可以理解为数组
    };
    
    
    //////////////////////////邻接链表相关函数定义///////////////
    Table Creat_Lable(int MaxElements)    //MaxElements参数为希望创建的节点数
    {
    
    	Table table1 = static_cast<Table> (malloc(sizeof(struct Led_table)));
    	table1->data = MaxElements;
    	if (table1 == NULL)
    	{
    		cout << "out of space!!!";
    	}
    
    	table1->firstedge = static_cast<position*>(malloc(sizeof(position)*(table1->data)));
    	if (table1->firstedge == NULL)
    	{
    		cout << "out of space!!!";
    	}
    
    	//给每个表头赋值,从0开始
    	for (int i = 0; i <= table1->data - 1; ++i)
    	{
    		table1->firstedge[i] = static_cast<position>(malloc(sizeof(EdgeNode)));   //申请一个节点
    		if (table1->firstedge[i] == NULL)
    		{
    			cout << "out of space!!!";
    		}
    		table1->firstedge[i]->adjvex = 0;   //表头这个参数没有意义
    		table1->firstedge[i]->weight = 0;   //表头这个参数没有意义
    		table1->firstedge[i]->dis = Inf;
    		table1->firstedge[i]->precursor = NotAVerter;
    		table1->firstedge[i]->next = NULL;
    
    	}
    	return table1;
    
    }
    
    
    void Insert(Table table1, int v, int w, int weig)   //表示存在一条边为<v,w>
    {
    	position p = static_cast<position>(malloc(sizeof(EdgeNode)));   //申请一个节点
    	if (p == NULL)
    	{
    		cout << "out of space!!!";
    	}
    	p->adjvex = w;
    	p->weight = weig;    //对于无权图来说,该域可以设置为1
    	p->dis = Inf;    //对于普通节点来说无意义
    	p->precursor = NotAVerter;  //对于普通节点来说无意义
    	p->next = table1->firstedge[v]->next;
    	table1->firstedge[v]->next = p;
    
    }
    
    void init_yuandian(Table table1, int s)  //把s设置为图的源点
    {
    	table1->firstedge[s]->adjvex = 0;
    	table1->firstedge[s]->weight = 0;
    	table1->firstedge[s]->dis = 0;    //源点的这个值设置为0
    	table1->firstedge[s]->precursor = NotAVerter;
    }
    
    
    bool Bellman_Ford(Table table1, int s)
    {
    	for (int i = 1; i <= table1->data - 1; ++i)   //每条边进行N-1次松弛操作
    	{
    		for (int j = 0; j <= table1->data - 1; ++j)  //对每条边
    		{
    			position p = table1->firstedge[j]->next;
    			while (p != NULL)
    			{
    				if (table1->firstedge[p->adjvex]->dis > table1->firstedge[j]->dis + p->weight)   //松弛操作
    				{
    					table1->firstedge[p->adjvex]->dis = table1->firstedge[j]->dis + p->weight;
    					table1->firstedge[p->adjvex]->precursor = j;
    				}
    				p = p->next;
    			}
    		}
    	}
    
    	bool flag = true;
    	for (int j = 0; j <= table1->data - 1; ++j)  //对每条边
    	{
    		position p = table1->firstedge[j]->next;
    		while (p != NULL)
    		{
    			if (table1->firstedge[p->adjvex]->dis > table1->firstedge[j]->dis + p->weight)
    			{
    				flag = false;
    				break;
    			}
    			p = p->next;
    		}
    	}
    	return flag;
    }
    
    void print_path(Table table1, int v)
    {
    	if (table1->firstedge[v]->precursor != NotAVerter)
    		print_path(table1, table1->firstedge[v]->precursor);
    	cout << "v" << v << endl;
    }
    
    
    
    
    int main()
    {
    	Table table_1 = Creat_Lable(5);    //创建一个大小为5的邻接表
    
    	Insert(table_1, 0, 1, 6); Insert(table_1, 0, 3, 7);
    	Insert(table_1, 1, 2, 5); Insert(table_1, 1, 3, 8); Insert(table_1, 1, 4, -4);
    	Insert(table_1, 2, 1, -2);
    	Insert(table_1, 3, 2, -3); Insert(table_1, 3, 4, 9);
    	Insert(table_1, 4, 0, 2); Insert(table_1, 4, 2, 7); 
    
    	init_yuandian(table_1, 0);  //把0设置为图的源点
    	cout << Bellman_Ford(table_1, 0) << endl;
    
    	cout << table_1->firstedge[4]->dis << endl;
    
    	print_path(table_1, 4);
    
    
    	return 0;
    }
    

      夜深了,夜更深了

  • 相关阅读:
    图像处理之图像分割
    matlab 矩阵运算技巧
    回溯法:八皇后问题
    spring框架学习笔记(二)
    spring框架学习笔记(一)
    java下搭建Webservice服务
    log4j使用
    Mybatis使用
    java序列化与反序列化
    java常用数据类型
  • 原文地址:https://www.cnblogs.com/1242118789lr/p/7648011.html
Copyright © 2020-2023  润新知