最短路径
两顶点间经过的边上权值之和最少的路径。
源点:第一个顶点
终点:最后一个顶点
Dijkstra 算法 O(n^2)
#define MAXX 65535
int a[10][10];//邻接矩阵,没有边就设为MAXX, i,j相等为0
int p[10];//最短路径下标,记录前一点的下标
int d[10];//到各点最短路径的权值和
void Dijkstra(int q)//q为出发点
{
int v,w,k,minn;
int f[10];//f[w]=1 表示w点被连
for(v=0;v<9;v++)
{
f[v]=0;
d[v]=a[q][v];
p[v]=0;
}
d[q]=0;
f[q]=1;
for(v=1;v<9;v++)
{
minn=MAXX;
for(w=0;w<9;w++)
{
if(!f[w]&&d[w]<minn)//找权值最小的点
{
k=w;
minn=d[w];
}
}
f[k]=1;
for(w=0;w<9;w++)
{
if(!f[w]&&(minn+a[k][w])<d[w])//改变d,p数组
{
d[w]=minn+a[k][w];
p[w]=k;
}
}
for(int i=0;i<9;i++)
cout<<p[i]<<" ";
cout<<endl;
}
}
单源最短路径
最后d数组的值表示源点到各点的最短路径数
p数组表示各点的前一点
Floyd O(n^3)
#define MAXX 65535
int a[10][10],d[10][10],p[10][10];
void Floyd(int a[10][10])
{
int v,k,w;
for(v=0; v<9; v++)
{
for(w=0; w<9; w++)
{
d[v][w]=a[v][w];
//cout<<d[v][w]<<" ";
p[v][w]=w;
}
}
for(k=0; k<9; k++)
for(v=0; v<9; v++)
for(w=0; w<9; w++)
{
if(d[v][w]>(d[v][k]+d[k][w]))
{
d[v][w]=d[v][k]+d[k][w];
p[v][w]=p[v][k];//经过下标为k的顶点
}
}
for(v=0;v<9;v++)
{
for(w=v+1;w<9;w++)
{
printf("v%d->v%d wight: %d",v,w,d[v][w]);
k=p[v][w];
printf("path: %d",v);
while(k!=w)
{
printf("->%d",k);
k=p[k][w];
}
printf("->%d\n",w);
}
printf("\n");
}
}
判断经过k点是否会减少路径长度是关键
代码简单,有点难理解,时间复杂度高