程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 單源最短路徑Bellman_Ford算法C++實現

單源最短路徑Bellman_Ford算法C++實現

編輯:C++入門知識

 

// 單源最短路徑Bellman_Ford算法.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include<iostream>

#define MAX 100

#define Infinity 65535

typedef int WeiType;

using namespace std;

 

struct edgeNode

{

 int no; //邊尾端的序號

 char info; //邊端的名稱

 WeiType weight; //邊權值

 struct edgeNode * next; //下一個

};

 

struct vexNode

{

 char info;  //節點名稱

 struct edgeNode *link; //與之相連的端點

};

//存儲節點信息

vexNode adjlist[MAX];

//前驅節點

int parent[MAX];

//源點到節點j最短路徑的花費

WeiType lowcost[MAX];

//建立鄰接表存儲

//adjlist為節點集,n為節點個數,e為邊數目

//返回源點序號

int createGraph(vexNode *adjlist,int n,int e)

{

 int i;

 for(i=1;i<=n;i++)

 {

  cout<<"請輸入節點"<<i<<"的名稱:";

  cin>>adjlist[i].info;

  adjlist[i].link = NULL;

  parent[i] = i;

  lowcost[i] = Infinity;

 }

 edgeNode *p1;

   int v1,v2;

   WeiType weight;

 for(i=1;i<=e;i++)

 {

  cout<<"請輸入邊"<<i<<"的起始節點與尾節點序號:";

  cin>>v1>>v2;

  cout<<"請輸入此邊的權值:";

  cin>>weight;

  p1 = (edgeNode*)malloc(sizeof(edgeNode));

  p1->no = v2;

  p1->weight = weight;

  p1->info = adjlist[v2].info;

  p1->next = adjlist[v1].link;

  adjlist[v1].link = p1;

 }

 cout<<"請輸入源點序號:";

 int v0;

 cin>>v0;

 lowcost[v0] = 0;

 return v0;

}

/*

//

void relax(WeiType *lowcost,int *parent,const int u,const int v,const WeiType w)

{

 if(lowcost[v]>lowcost[u]+w)

 {

  lowcost[v] = lowcost[u] + w;

  parent[v] = u;

 }

}

*/

//

bool Bellman_Ford(vexNode *adjlist,WeiType *lowcost,int *parent,const int n)

{

 int i,j;

 for(j=1;j<n;j++)

 {

  for(i=1;i<=n;i++)

  {

   edgeNode *p1 = adjlist[i].link;

   while(p1 != NULL)

   {

    if(lowcost[i]+p1->weight <lowcost[p1->no])

    {

     lowcost[p1->no] = lowcost[i]+p1->weight;

     parent[p1->no] = i;

    }

    p1 = p1->next;

   }

  }

 }

 //檢查有無負回路

  for(i=1;i<=n;i++)

  {

   edgeNode *p2 = adjlist[i].link;

   while(p2 != NULL)

   {

    if(lowcost[p2->no]>lowcost[i]+p2->weight)

     return false;

    p2 = p2->next;

   }

  }

 return true;

}

//打印源點到節點i最短路徑

void print_it(vexNode *adjlist,int *parent,const int v0,const int i)

{

 if(i == v0)

  cout<<"("<<v0<<":"<<adjlist[v0].info<<")  ";

 else

 {

  print_it(adjlist,parent,v0,parent[i]);

  cout<<"("<<i<<":"<<adjlist[i].info<<")  ";

 }

}

int _tmain(int argc, _TCHAR* argv[])

{

 int cases;

 cout<<"請輸入案例的個數:";

 cin>>cases;

 while(cases--)

 {

  int n,e;

  cout<<"請輸入節點數:";

  cin>>n;

  cout<<"請輸入邊數:";

  cin>>e;

  //創建鄰接表

  int v0 = createGraph(adjlist,n,e);

  //調用Bellman-Ford算法

  bool flag = Bellman_Ford(adjlist,lowcost,parent,n);

  int i;

  //輸出源點到其余每一點的最短路徑(節點序號:節點名稱)

  for(i=1;i<=n;i++)

  {

   cout<<"從源點"<<adjlist[v0].info<<"到點"<<adjlist[i].info<<"的路徑為:"<<endl;

   print_it(adjlist,parent,v0,i);

     cout<<endl;

   cout<<"此路徑花費為:"<<lowcost[i]<<endl;

 

  }

 }

 system("pause");

 return 0;

}

--------------------------------------------------------程序測試--------------------------------------------------------

\

 

                                                           

請輸入案例的個數:1

請輸入節點數:5

請輸入邊數:10

請輸入節點1的名稱:s

請輸入節點2的名稱:t

請輸入節點3的名稱:x

請輸入節點4的名稱:y

請輸入節點5的名稱:z

請輸入邊1的起始節點與尾節點序號:1 2

請輸入此邊的權值:6

請輸入邊2的起始節點與尾節點序號:1 4

請輸入此邊的權值:7

請輸入邊3的起始節點與尾節點序號:2 3

請輸入此邊的權值:5

請輸入邊4的起始節點與尾節點序號:2 4

請輸入此邊的權值:8

請輸入邊5的起始節點與尾節點序號:2 5

請輸入此邊的權值:-4

請輸入邊6的起始節點與尾節點序號:3 2

請輸入此邊的權值:-2

請輸入邊7的起始節點與尾節點序號:4 3

請輸入此邊的權值:-3

請輸入邊8的起始節點與尾節點序號:4 5

請輸入此邊的權值:9

請輸入邊9的起始節點與尾節點序號:5 1

請輸入此邊的權值:2

請輸入邊10的起始節點與尾節點序號:5 3

請輸入此邊的權值:7

請輸入源點序號:1

從源點s到點s的路徑為:

(1:s)

此路徑花費為:0

從源點s到點t的路徑為:

(1:s)  (4:y)  (3:x)  (2:t)

此路徑花費為:2

從源點s到點x的路徑為:

(1:s)  (4:y)  (3:x)

此路徑花費為:4

從源點s到點y的路徑為:

(1:s)  (4:y)

此路徑花費為:7

從源點s到點z的路徑為:

(1:s)  (4:y)  (3:x)  (2:t)  (5:z)

此路徑花費為:-2

請按任意鍵繼續. . .

 

摘自 heyongluoyao8

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved