结果
数据为项目目录下的 mat.txt 文件。
5
0 10 999 30 100
999 0 50 999 999
999 999 0 999 10
999 999 20 0 60
999 999 999 999 0
/********************************************************************
* FILER.H 文件注释
* 文件路径: D:\EVERBOX\SOURCE CODE\贪心法\单源最短路径/
* 作者 : mpl2
* 创建时间: 2011/12/3 20:34
* 文件描述:
*********************************************************************/
#ifndef _FILER_H_
#define _FILER_H_
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
/*
* 打开文件,转换为数组。格式:第一行为数组大小,从第二行开始为数据,以
* 制表符\t为分隔符。
*/
int fileRead(const char* filePath,int** &returnArray);
#endif
/********************************************************************
* FILER.CPP 文件注释
* 文件路径: D:\EVERBOX\SOURCE CODE\贪心法\单源最短路径/
* 作者 : mpl2
* 创建时间: 2011/12/3 20:34
* 文件描述:
*********************************************************************/
#include "fileR.h"
int fileRead(const char* filePath,int** &returnArray){
if( !filePath ){
returnArray = NULL;
return 0;
}
FILE* fp = fopen(filePath, "r");
if( fp == NULL){
printf("ERROR:File not exist\n");
exit(-1);
}
int arrayNum = 0;
//fread(&arrayNum, sizeof(int), 3, fp);
fscanf(fp, "%d\n", &arrayNum);
returnArray = (int**)malloc( (arrayNum+1)*sizeof(int*) );
if( arrayNum > 0 ){
for (int i = 0; i < arrayNum+1 ; i++ ) {
returnArray[i] = (int*)malloc( (arrayNum+1)*sizeof(int) );
}
for (int j = 1; j < arrayNum+1 ; j++ ) {
for (int x = 1; x < arrayNum+1 ; x++ ) {
if ( x == arrayNum ) {/* 假如读到每行最后一个数字 */
fscanf(fp, "%d\n", &(returnArray[j][x] ));
}else
fscanf(fp, "%d\t", &(returnArray[j][x] ));
}
}
}
fclose(fp);
return arrayNum;
}
/********************************************************************
* MAIN2.CPP 文件注释
* 文件路径: D:\EVERBOX\SOURCE CODE\贪心法\单源最短路径/
* 作者 : mpl2
* 创建时间: 2011/12/3 20:33
* 文件描述:
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "fileR.h"
#define MAX_INT 999
/*
* n表示节点数,v表示源节点;
* dist[i:n];表示第i个点到第n个点的最短特殊路径长度;
* c[i][j]表示边(i,j)的权;
*/
void Dijkstra(int n,int v,int* dist,int* prev,int** c){
// 下标从1开始,s数组表示是否在S集合中.范围是 1 到 n
bool* s = (bool*)malloc( (n+1) * sizeof(bool) );
for(int i=1; i <= n; i++){
//初始化时,只有v在集合S中,其余节点都不在
dist[i] = c[v][i];
s[i] = false;
// 假如源节点没有直接到第i个节点
if( dist[i] == MAX_INT ){
prev[i] = 0;
}else{
prev[i] = v;
}
}
dist[0] = 0;//v到v的距离是0
s[v] = true;//初始化v就在集合s中
// dist数组 [2:n]需要完成
for(int i=1; i <= n-1; i++){
int tem = MAX_INT;
int u = v;//表示当前在集合S中的点
// 从不在集合s中的点,选取一个距源点v最短的一个点
for(int j=1; j <= n; j++){
if( !s[j] && dist[j]<tem){
tem = dist[j];
u = j;
}
}
s[u] = true; // 将选出的距离最短的点放入集合S
//将u放入集合S后,更新dist数组
// if dist[u] + c[u][j] < dist[j] 需要更新 dist[j] , prev[j]
for(int j=1; j <= n; j++){
if ( dist[j] > dist[u] + c[u][j] ) {
dist[j] = dist[u] + c[u][j];
prev[j] = u;
}
}
}
free(s);
}
/*
for (int i = num; i >= 2 ; i-- ) {
printf("点%d 到 点%d 的最短路径长度: %d\n", v, i, dist[i]);
int p = prev[i];
while ( p != 0 ) {
printf(" %d ",p);
p = prev[p];
}
printf("\n",p);
}*/
void showPath( int* prev,int p, int endP){
if ( p != endP ) {
showPath( prev, prev[p], endP);
printf("%d ",prev[p]);
}
}
int main(){
int** c = 0;
int v = 1;
int num = fileRead("mat.txt", c);
int* dist = (int*)malloc((num+1)*sizeof(int));
int* prev = (int*)malloc((num+1)*sizeof(int));
prev[0] = 0;
prev[1] = 0;
dist[0] = 0;
dist[1] = 0;
/*
for (int i = 1; i < num+1 ; i++ ) {
for (int j = 1; j < num+1 ; j++ ) {
if ( j == num ) {
printf("%d\n",c[i][j]);
}else
printf("%d\t",c[i][j]);
}
}*/
printf("input the source node v :");
scanf("%d",&v);
printf("\n\n" );
Dijkstra(num, v, dist, prev, c);
/*
for ( int i = 0; i < num+1; i++ ) {
printf("%d ",prev[i]);
}
printf("\n " );
for ( int i = 0; i < num+1; i++ ) {
printf("%d ",dist[i]);
}*/
for (int i = num; i >= 2 ; i-- ) {
if ( dist[i] != MAX_INT && dist[i] > 0) {
printf("point %d to point %d, lenth is: %d\n", v, i, dist[i]);
printf("the path is :" );
showPath( prev, i , v);
printf("\n\n" );
}
}
return 0;
}