您的位置:首页 > 其它

图论 回顾最短路写法(Dijktra和Floyd)

2017-12-08 23:59 288 查看
下面是Dijkstra算法求最短路

/*
严格参照《数据结构(严蔚敏版)》
2017.12.6
by kk
*/

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#define infinity 0x3f3f3f3f
#define maxsize 100
using namespace std;
typedef int VertexType;
typedef int ElemType;
typedef char InfoType;
typedef int shortPathTable[maxsize];
typedef int pathMatrix[maxsize];
typedef struct
{
ElemType data;
InfoType info;
} Matrix;
typedef struct
{
VertexType ver[maxsize];
Matrix arc[maxsize][maxsize];
int numVer,numEdge;
int kind;
} GraphM;
void createMatrix(GraphM &g)
{
scanf("%d%d",&g.numVer,&g.numEdge);
int i,j;
for(i=0; i<g.numVer; i++)
scanf("%d",&g.ver[i]);
for(i=0; i<g.numVer; i++)
for(j=0; j<g.numVer; j++)
g.arc[i][j].data=infinity;
int x,y,w;
for(i=0; i<g.numEdge; i++)
{
scanf("%d%d%d",&x,&y,&w);
g.arc[x][y].data=w;
g.arc[y][x].data=w;
}
}//以上是在建邻接矩阵,具体解释就看以前的文章了
void shortestPath_Dijkstra(GraphM G,int x,pathMatrix &P,shortPathTable &D)
{
/*
其实感觉dijkstra算法跟prim求最小生成树算法差不多
这里的P数组就相当于adjvex数组,D数组就相当于lowcost数组,final数组的作用跟
vis的数组作用一样.其实prim中也是有vis数组的,只是用lowcost数组代替了,lowcost数组
有两个作用,一个是标记哪个点已经选取了,一个是当前可选择边的长度。

*/
int i,j;

int Final[maxsize];
memset(Final,0,sizeof(Final));
for(i=0; i<G.numVer; i++)
P[i]=x;//所有节点都是从x出发
Final[x]=1;//x结点已经到过了
for(i=0; i<G.numVer; i++)
D[i]=G.arc[x][i].data;
//开始只有x结点,那么到各点的距离就由x决定,当加入其他点后,就得由几个点一起决定,
//即下面for循环代码做的工作

D[x]=0;//自己到自己当然距离为0
int Min,k;
for(i=1; i<G.numVer; i++)
{
Min=infinity;
for(j=0; j<G.numVer; j++)
if(!Final[j]&&D[j]<Min)
{
Min=D[j];
k=j;
}
Final[k]=1;
for(j=0; j<G.numVer; j++)
{
if(!Final[j]&&(Min+G.arc[k][j].data)<D[j])
{
D[j]=Min+G.arc[k][j].data;
P[j]=k;
}
}
}

printf("pathMatrix[]:\n");
for(i=0; i<G.numVer; i++)
printf("%3d ",P[i]);
puts("");
printf("shortPathTable[]:\n");
for(i=0; i<G.numVer; i++)
printf("%3d ",D[i]);
puts("");

//get path
/*
int path_count=0;
int v0=x;
int path[maxsize];
path[path_count++]=8;
int r=8;
while(P[r]!=x){
path[path_count++]=P[r];
r=P[r];
}
path[path_count++]=x;
for(i=path_count-1;i>=0;--i)
printf("%d ",path[i]);
printf("\n");
*/
}
int main()
{
GraphM G;
createMatrix(G);
pathMatrix P;
shortPathTable D;
shortestPath_Dijkstra(G,0,P,D);

return 0;
}
/*

/*
5 6
0 1 2 3 4
0 1 9
0 2 2
0 4 6
1 2 3
2 3 5
3 4 1

9 16
0 1 2 3 4 5 6 7 8
0 1 1
0 2 5
1 2 3
1 4 5
1 3 7
2 4 1
2 5 7
3 4 2
3 6 3
4 6 9
4 5 3
4 7 9
5 7 5
6 7 2
6 8 7
7 8 4
*/



下面是弗洛伊德算法求zuiduanl
/*
严格参照《数据结构(严蔚敏版)》
2017.12.6
by kk
*/

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#define infinity 0x3f3f3f3f
#define maxsize 100
using namespace std;
typedef int VertexType;
typedef int ElemType;
typedef char InfoType;
typedef int shortPathTable[maxsize][maxsize];
typedef int pathMatrix[maxsize][maxsize];
typedef struct
{
ElemType data;
InfoType info;
} Matrix;
typedef struct
{
VertexType ver[maxsize];
Matrix arc[maxsize][maxsize];
int numVer,numEdge;
int kind;
} GraphM;
void createMatrix(GraphM &g)
{
scanf("%d%d",&g.numVer,&g.numEdge);
int i,j;
for(i=0; i<g.numVer; i++)
scanf("%d",&g.ver[i]);
for(i=0; i<g.numVer; i++)
for(j=0; j<g.numVer; j++)
g.arc[i][j].data=infinity;
int x,y,w;
for(i=0; i<g.numEdge; i++)
{
scanf("%d%d%d",&x,&y,&w);
g.arc[x][y].data=w;
g.arc[y][x].data=w;
}
}
//以上是邻接矩阵建图,以前的文章有详细解释

void shortestPath_Floyd(GraphM G,pathMatrix &P,shortPathTable &D)
{
int i,j,k;
for(i=0; i<G.numVer; i++)//首先对D矩阵和P矩阵进行初始化
for(j=0; j<G.numVer; j++)
{
D[i][j]=G.arc[i][j].data;
P[i][j]=j;
}
//D矩阵用原始邻接矩阵初始化,P矩阵用坐标的j坐标初始化
//ShortPathTable矩阵(即D矩阵)里[v][w]代表v到w的最短距离,P矩阵用来记录路径

//以下是三层循环
for(k=0; k<G.numVer; k++)//第一层
{

for(i=0; i<G.numVer; i++)//第二和第三层是在遍历整个D矩阵
{
for(j=0; j<G.numVer; j++)
{
if(D[i][j]>(D[i][k]+D[k][j]))
{
D[i][j]=D[i][k]+D[k][j];
P[i][j]=P[i][k];
}
}
}
//如果发现D[i][j]>(D[i][k]+D[k][j])那么就D[i][j]将改为D[i][k]+D[k][j]

}

}
void showPath(GraphM G,pathMatrix P,shortPathTable D,int x,int y)
{
//打印路径时,在PathMatirx矩阵里找x到y路径时,就找到y那一列进行操作,比如说0->8,则从p[0][8]
//开始
int i,j;
printf("%d-%d %d\n",x,y,D[x][y]);
int k=P[x][y];
printf("path:%d ",x);
while(k!=y)
{
printf("%d ",k);
k=P[k][y];
}
printf("%d\n",y);

}
int main()
{
//Floyd算法是可以求多源点最短路的,Dijktra算法是单源点的
GraphM G;
createMatrix(G);
shortPathTable D;
pathMatrix P;
shortestPath_Floyd(G,P,D);
showPath(G,P,D,0,8);
showPath(G,P,D,1,7);
return 0;
}
/*

/*
5 6
0 1 2 3 4
0 1 9
0 2 2
0 4 6
1 2 3
2 3 5
3 4 1

9 16
0 1 2 3 4 5 6 7 8
0 1 1
0 2 5
1 2 3
1 4 5
1 3 7
2 4 1
2 5 7
3 4 2
3 6 3
4 6 9
4 5 3
4 7 9
5 7 5
6 7 2
6 8 7
7 8 4
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: