版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/84480132
Floyd算法和Dijkstra算法都不能针对带有负权边的图,否则一直走负权边,没有最小,只有更小!!
Floyd算法
import java.util.Scanner;
//Floyd算法
class Graph{
public int[][] adjacencyMatrix;
public int vertexNumber;
public int arcNumber;
public static final int INF = 1000000;//这个值要设置的刚刚好,后面存在加运算,以防溢出
public void createGraph(){
Scanner scan = new Scanner(System.in);
System.out.print("请输入图的顶点数:");
vertexNumber = scan.nextInt();
System.out.print("请输入图的边数:");
arcNumber = scan.nextInt();
adjacencyMatrix = new int[vertexNumber][vertexNumber];
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++){
adjacencyMatrix[i][j] = Graph.INF;
}
}
for(int i = 0; i < vertexNumber; i++){
adjacencyMatrix[i][i] = 0;
}
System.out.println("请输入各条边(顶点+空格+顶点+边权):");
for(int i = 0; i < arcNumber; i++){
int x = scan.nextInt();
int y = scan.nextInt();
int w = scan.nextInt();
adjacencyMatrix[x-1][y-1] = adjacencyMatrix[y-1][x-1] = w;
}
}
public void floyd(){
for(int k = 0; k < vertexNumber; k++){
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++){
if(adjacencyMatrix[i][k] + adjacencyMatrix[k][j] < adjacencyMatrix[i][j]){
adjacencyMatrix[i][j] = adjacencyMatrix[i][k] + adjacencyMatrix[k][j];
}
}
}
}
}
}
public class Main {
public static void main(String[] args){
Graph g = new Graph();
g.createGraph();
g.floyd();
for(int i = 0; i < g.vertexNumber; i++){
System.out.print(g.adjacencyMatrix[0][i]+" ");
}
System.out.println();
}
}
Dijkstra算法
import java.util.Scanner;
//Floyd算法
class Graph{
public int[][] adjacencyMatrix;
public int vertexNumber;
public int arcNumber;
public boolean[] visited;
public int[] distance;
public int[] pre;//记录路径
public static final int INF = 1000000;//这个值要设置的刚刚好,后面存在加运算,以防溢出
public void createGraph(){
Scanner scan = new Scanner(System.in);
System.out.print("请输入图的顶点数:");
vertexNumber = scan.nextInt();
System.out.print("请输入图的边数:");
arcNumber = scan.nextInt();
adjacencyMatrix = new int[vertexNumber][vertexNumber];
visited = new boolean[vertexNumber];
distance = new int[vertexNumber];
pre = new int[vertexNumber];
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++){
adjacencyMatrix[i][j] = Graph.INF;
}
}
for(int i = 0; i < vertexNumber; i++){
adjacencyMatrix[i][i] = 0;
distance[i] = Graph.INF;
visited[i] = false;
pre[i] = -1;
}
System.out.println("请输入各条边(顶点+空格+顶点+边权):");
for(int i = 0; i < arcNumber; i++){
int x = scan.nextInt();
int y = scan.nextInt();
int w = scan.nextInt();
adjacencyMatrix[x-1][y-1] = adjacencyMatrix[y-1][x-1] = w;
}
}
public void dijkstra(int st){
distance[st] = 0;
for(int i = 0; i < vertexNumber; i++){
int pos = st;
int min = Graph.INF;
//找到一个向外扩展的顶点
for(int j = 0; j < vertexNumber; j++){
if(visited[j] == false && distance[j] < min){
pos = j;
min = distance[j];
}
}
if(min == Graph.INF){//说明后继没有相连顶点了
break;
}
visited[pos] = true;
for(int j = 0; j < vertexNumber; j++){
if(visited[j]==false && distance[pos] + adjacencyMatrix[pos][j] < distance[j] ){
distance[j] = distance[pos] + adjacencyMatrix[pos][j];
pre[j] = pos;
}
}
}
//打印st到各个顶点的最短路径及距离
for(int i = 0; i < vertexNumber; i++){
print(pre[i]);
System.out.println(i+1);
System.out.println("distance: "+distance[i]);
}
}
public void print(int en){
if(en == -1){
return;
}
print(pre[en]);
System.out.print((en+1)+"->");
}
}
public class Main {
public static void main(String[] args){
Graph g = new Graph();
g.createGraph();
g.dijkstra(0);
}
}