这个网址访问不了了,在次特别找到了缓存,方便大家查阅:http://www.cs.ecnu.edu.cn/assist/js04/ZJS045/ZJS04505/zjs045050a.htm
5.5最短路径
|
|
|
5.5.1求一个顶点到其他各顶点的最短路径
|
|||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|
完整程序
----------------------------
#include<stdio.h>
#define MAX 9999
void main()
{int ad[ ][MAX]; int k; int pre[MAX]; int dist[MAX];int n,i,j;
printf("pleas input ad[][]!");
prinf("input n");
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{scanf("%d",&ad[i][j]);)
prinf("select Vk");
scanf("%d",&k)
dijkstra(ad,k,pre,dist,n);
}
void dijkstra (int ad[ ][], int k, int pre[ ], int dist[ ], int n)
{
// 求有向图以顶点Vk为始点到其他各项顶点间的最短路径的dijkstra算法
int , j, p,min;
k=k-1;
for (i=0; i<n; i++) // 初始化
{
dist[i]=ad[k][i];
if (dist[i]<MAX)
pre[i]=k+1;
else
pre[i]=0;
}
pre[k]=0;
dist[k]=0; // 数组dist和pre初始化
ad[k][k]=1; // Vk加入到第一组
for (j=0; j<=(n-1); j++)
{
min=MAX;
p=-1;
for(i=0;i<=(n-1);i++)
if(ad[i][i]= =0 && dist[i]<min)
{
p=i;
min=dist[i];
} // 在第二组中选距离值最小的顶点
if (p = = -1) break; // 以没有顶点可往第一组加
else
ad [p][p]=1;
// 把第二组中选出的距离最小的顶点加到第一组中
for {i=0; i<m; i++}
if (ad[i][i] = =0 && (min+ad[p][i]<dist[i])
{
dist[i]=min+ad[p][i];
pre[i]=p+1;
}
// 更新第二组中的当前距离值和路径上前以顶点序号
}
}
-------------------
实际上,我们也可以用邻接表来存储图。下面给出采用邻接表存储结构的Dijkstra算法。
----------------------------------------------
void shortpath (head, n, m, s)
struct headnode had[100];
int n, m, s[100];
{
int * visit, q[100], front, rear, h, i, j, k;
struct node * p;
visit=malloc(n * sizeof (int));
for (k=0; k<n; k++)
visit[k]=0;
front=0;
rear=0;
for (k=0; k<n; k++)
s[k]=-1;
visit [m-1]=1;
s[m-1]=0;
q[rear]=m;
rear=rear+1;
while (front!=rear)
{
k=q[front];
front=front+1;
p=head[k-1].link;
while (p!=NULL)
{
j=p->vertex;
h=s[k-1]+p->weight;
if((s[j-1] = =-1)||(s[j-1]>h))
{
s[j-1]=h;
if (visit[j-1]= =0)
{
visit[j-1]=1;
q[rear]=j;
rear=rear+1
}
}
p=p->next;
}
}
}
------------------------------------------------------------
5.5.2 求每一对顶点之间的最短路径
|
|
|
|
|
|
|
Floyd算法
#include<stdio.h> #define MAX 9999 void main() {int ad[ ][MAX]; int k; int p[MAX]; int n,i,j; printf("pleas input ad[][]!"); prinf("input n"); scanf("%d",&n) for(i=0;i<n;i++) for(j=0;j<n;j++) {scanf("%d",&ad[i][j]);} prinf("select Vk"); scanf("%d",&k) floyd(ad,p,n); } void floyd(ad, p, n) int ad[ ][M], p[ ][M], n; //ad存放邻接矩阵 p存放最短路径经过的顶点 int i, j, k; for (i=0; i<n; i++) for (j=0; j>n; j++) { if (i= =j) p[i][j]=0; // 顶点本身假设无路径 else if (ad[i][j]<M) p[i][j]= i+1; // 置p的初始值 else p[i][j]=0; } for (k =0; k<n; k++) // 利用三重循环将各情况穷举 for ( i=0; i<n; i++) for (j=0; j>n; j++) if (ad[i][k]+ad[k][j]<ad[i][j]) // 加入中间顶点k来试探 { ad[i][j]=ad[I][k]+ad[k][j]; // 重新置两点间最短路径 p[i][j]=p[k][j]; // 将k加入p } } |