1. 程式人生 > >Floyd 演算法(最短路徑)

Floyd 演算法(最短路徑)

基本思想: 

1,從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。

2,對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比已知的路徑更短。如果是更新它。

時間複雜度:O(n^{3})

參考:弗洛伊德(Floyd)演算法求圖的最短路徑  --- JeffCoding

程式碼:

#include<stdio.h>
#include<memory.h>
#define MAX 1000000

int graph[100][100];   //存放邊集及其權重 

int path[100][100];  //存放最短路徑 中除了起點終點的 第一個節點 

int vertex[100];  //存放是否遍歷過 

int dis[100];

void Creat_G(int vertnum){
	memset(graph,0,sizeof(graph));
	printf("輸入圖的鄰接矩陣:\n");
	
	int i,j;
	for(i=1;i<=vertnum;i++){
		for(j=1;j<=vertnum;j++){
			scanf("%d",&graph[i][j]);
			if(graph[i][j]==0) {
				graph[i][j]=MAX;       //如果兩點之間沒有邊這初始化graph為MAX
			}
			path[i][j]=j;   //初始化開始時的i,j兩點間的最短路徑的後繼為 j 
		}
	}
	
	printf("建立完成\n----------------------\n");
} 

void Floryd(int vertnum){
	int u,v,w,i;   //u 中間點  v 起始點  w 終點
	for(u=1;u<=vertnum;u++){
		for(v=1;v<=vertnum;v++){
			for(w=1;w<=vertnum;w++){
				if(v!=w && graph[v][w]>graph[v][u]+graph[u][w]){
					graph[v][w]=graph[v][u]+graph[u][w];
					path[v][w]=path[v][u];	// 更新最短路徑中的除v,w外的第一個節點 
				}	
			}
		}
	}
}



int main(){
	int num;
	printf("輸入點的個數:\n");
	scanf("%d",&num);
	printf("-------------------------\n");
	Creat_G(num);
	Floryd(num);
	int i,j,u;
	for(i=1;i<=num;i++){
		for(j=1;j<=num;j++){
			printf("< %d , %d >  ",i,j);
			if(graph[i][j]==MAX)
				printf("$\t\n");
			else{
			
				printf("%d\t",graph[i][j]);
				u=path[i][j];
				printf("%d",i);
				for(;u!=j;u=path[u][j]){    //輸出最短路徑 
						printf("->%d",u); 
				}
				printf("->%d\n",j);
			}
		}
	}
	


	return 0;
}