// 單源最短路徑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