**
The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative.
**
import java.io.IOException;
import java.util.Scanner;
public class Bellman_Ford {
public class ENode2 {
int weight;
int ivex; // 该边所指向的顶点的位置
ENode2 nextEdge; // 指向下一条弧的指针
}
// 邻接表中表的顶点
private class VNode2 {
int d;
VNode2 pre;
char data; // 顶点信息
ENode2 firstEdge; // 指向第一条依附该顶点的弧
};
private VNode2[] mVexs; // 顶点数组
/*
* 创建图(自己输入数据)
*/
public Bellman_Ford() {
// 输入"顶点数"和"边数"
System.out.printf("input vertex number: ");
int vlen = readInt();
System.out.printf("input edge number: ");
int elen = readInt();
if (vlen < 1 || elen < 1 || (elen > (vlen * (vlen - 1)))) {
System.out.printf("input error: invalid parameters!\n");
return;
}
// 初始化"顶点"
mVexs = new VNode2[vlen];
for (int i = 0; i < mVexs.length; i++) {
System.out.printf("vertex(%d): ", i);
mVexs[i] = new VNode2();
mVexs[i].data = readChar();
mVexs[i].firstEdge = null;
}
// 初始化"边"
// mMatrix = new int[vlen][vlen];
for (int i = 0; i < elen; i++) {
// 读取边的起始顶点和结束顶点
System.out.printf("edge(%d):", i);
char c1 = readChar();
char c2 = readChar();
int w = readInt();
int p1 = getPosition(c1);
int p2 = getPosition(c2);
// 初始化node1
ENode2 node1 = new ENode2();
node1.ivex = p2;
node1.weight = w;
// 将node1链接到"p1所在链表的末尾"
if (mVexs[p1].firstEdge == null)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
}
}
public Bellman_Ford(char[] vexs, char[][] edges, int[] weigh) {
// 初始化"顶点数"和"边数"
int vlen = vexs.length;
int elen = edges.length;
// 初始化"顶点"
mVexs = new VNode2[vlen];
for (int i = 0; i < mVexs.length; i++) {
mVexs[i] = new VNode2();
mVexs[i].data = vexs[i];
mVexs[i].firstEdge = null;
}
// 初始化"边"
for (int i = 0; i < elen; i++) {
// 读取边的起始顶点和结束顶点
char c1 = edges[i][0];
char c2 = edges[i][1];
// 读取边的起始顶点和结束顶点
int p1 = getPosition(edges[i][0]);
int p2 = getPosition(edges[i][1]);
// 初始化node1
ENode2 node1 = new ENode2();
node1.ivex = p2;
// 将node1链接到"p1所在链表的末尾"
if (mVexs[p1].firstEdge == null)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
node1.weight = weigh[i];
}
}
public void Initialize() {
for (int i = 0; i < mVexs.length; i++) {
mVexs[i].d = Integer.MAX_VALUE;
// mVexs[i].pre = null;
}
mVexs[0].d = 0;
}
public boolean Bellman_Ford() {
Initialize();// 初始化
// System.out.println("输出最短路径:");
// System.out.printf("%c",mVexs[0].data );
for (int i = 0; i < mVexs.length; i++) {
for (int j = 0; j < mVexs.length; j++) {
ENode2 node = mVexs[j].firstEdge;
while (node != null) {
if (mVexs[node.ivex].d > mVexs[j].d + node.weight) {//进行relax操作
mVexs[node.ivex].d = mVexs[j].d + node.weight;
}
// Relax(mVexs[i], mVexs[node.ivex]);
node = node.nextEdge;
}
}
}
for (int k = 0; k < mVexs.length; k++) {
ENode2 node = mVexs[k].firstEdge;
while (node != null) {
if (mVexs[(node.ivex)].d > mVexs[k].d + node.weight) {
return false;
}
node = node.nextEdge;
}
}
return true;
}
//输出源点s到每个节点的最短路径
public void Distance() {
System.out.print("输出源点s到每个节点的最短路径:");
for (int i = 0; i < mVexs.length; i++) {
System.out.print(mVexs[i].data+":"+mVexs[i].d+" ");
}
System.out.println();
}
//输出最短路径
public void SmallPath_output() {
boolean temp = Bellman_Ford();
if (temp == false) {
System.out.println("存在权重为负值的环路!");
} else {
System.out.println("输出最短路径为:");
for (int i = 0; i < mVexs.length; i++) {
ENode2 node = mVexs[i].firstEdge;
while (node != null) {
if (mVexs[(node.ivex)].d == mVexs[i].d + node.weight&&node.ivex==0) {
System.out.println("指向源节点的不输出!");
}
else if(mVexs[(node.ivex)].d == mVexs[i].d + node.weight){
System.out.println(mVexs[i].data + "-->" + mVexs[(node.ivex)].data + " " + node.weight);
}
node = node.nextEdge;
}
}
}
}
//输出每条边的权重
public void PrintWeight() {
for (int i = 0; i < mVexs.length; i++) {
ENode2 node = mVexs[i].firstEdge;
while (node != null) {
System.out.println(mVexs[i].data+"-->"+mVexs[node.ivex].data+" "+node.weight);
node = node.nextEdge;
}
}
}
/*
* 将node节点链接到list的最后
*/
private void linkLast(ENode2 list, ENode2 node) {
ENode2 p = list;
while (p.nextEdge != null)
p = p.nextEdge;
p.nextEdge = node;
}
/*
* 返回ch位置
*/
private int getPosition(char ch) {
for (int i = 0; i < mVexs.length; i++)
if (mVexs[i].data == ch)
return i;
return -1;
}
/*
* 读取一个输入字符
*/
private char readChar() {
char ch = '0';
do {
try {
ch = (char) System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
return ch;
}
/*
* 读取一个输入字符
*/
private int readInt() {
Scanner scanner = new Scanner(System.in);
return scanner.nextInt();
}
/*
* 打印矩阵队列图
*/
public void Graph_Print() {
System.out.println("List Graph:");
for (int i = 0; i < mVexs.length; i++) {
System.out.print( i+"("+ mVexs[i].data+"):");
ENode2 node = mVexs[i].firstEdge;
while (node != null) {
System.out.print( node.ivex+"("+ mVexs[i].data+"-"+node.weight+"->"+ mVexs[node.ivex].data+")");
System.out.printf("\t");
node = node.nextEdge;
}
System.out.printf("\n");
}
}
public static void main(String[] args) {
int[] weight = { 6, 7, 5, 8, -4, -2, -3, 9, 2, 7 };
char[] vexs = { 'A', 'B', 'C', 'D', 'E' };
char[][] edges = new char[][] { { 'A', 'B' }, { 'A', 'D' }, { 'B', 'C' }, { 'B', 'D' }, { 'B', 'E' },
{ 'C', 'B' }, { 'D', 'C' }, { 'D', 'E' }, { 'E', 'A' }, { 'E', 'C' }, };
Bellman_Ford bf = new Bellman_Ford(vexs, edges, weight);
bf.PrintWeight();
bf.Graph_Print();
//bf.Bellman_Ford();
System.out.println(bf.Bellman_Ford());
bf.Distance();
bf.SmallPath_output();
}
}