#include<stdio.h>
int V[50][50];
int a[50],b[20];
int static k,n,m;
void createGraph()
{
int i,j,t,s;
printf("请输入结点数:");
scanf("%d",&n);
for(i=0; i<=n; i++)
for(j=0; j<=n; j++)
V[i][j]=0;//初始化V[i][j]=0,表示两结点没有边相连
printf("输入图的层数:");
scanf("%d",&k);
printf("请输入每层的结点数的最大编号:");
a[0]=0;
for(i=1; i<=k; i++)
scanf("%d",&a[i]);
printf("请输入边数:");
scanf("%d",&m);
printf("请输入结点之间的关系(如:结点i和结点j的距离为s,则输入i,j,s)\n");
for(t=1; t<=m; t++)
{
scanf("%d%d%d",&i,&j,&s);
V[i][j]=s;
}
}
int Backward()//向后求解法
{
int i,j,t,r;
for(i=a[1]+1; i<=a[2]; i++) //把第二层每个结点i与第一层结点s的边距赋值给V[i][i]
V[i][i]=V[1][i];
for(r=2; r<k; r++) //向后逐层求解
for(i=a[r-1]+1; i<=a[r]; i++) //遍历第r层的每个结点i与第(r+1)层结点j之间的边距,选择此刻最优解
for(j=a[r]+1; j<=a[r+1]; j++)
{
if(V[i][j]!=0&&V[j][j]==0)//第一次把此刻路径长度赋给V[j][j]
V[j][j]=V[i][i]+V[i][j];
else if(V[i][j]!=0&&V[j][j]!=0)
{
if((V[i][i]+V[i][j])<V[j][j])
V[j][j]=V[i][i]+V[i][j];
}
}
j=-1;
b[4]=0;
for(r=k-1; r>=2; r--)
for(i=a[r]+1; i<=a[r+1]; i++)
{
if(b[r]==j)
break;
for(j=a[r-1]+1; j<=a[r]; j++)
if((V[i][i]-V[j][i])==V[j][j])
{
b[r]=j;
break;
}
}
return V[n][n];
}
int Forward()//向前求解法
{
int i,j,t,r;
for(i=a[k-2]+1; i<=a[k-1]; i++) //把第二层每个结点i与第一层结点s的边距赋值给V[i][i]
V[i][i]=V[i][a[k]];
for(r=k-1; r>1; r--) //向前逐层求解
for(j=a[r-1]+1; j<=a[r]; j++)//遍历第r层的每个结点i与第(r-1)层结点j之间的边距,选择此刻最优解
for(i=a[r-2]+1; i<=a[r-1]; i++)
{
if(V[i][j]!=0&&V[i][i]==0)//第一次把此刻路径长度赋给V[j][j]
V[i][i]=V[j][j]+V[i][j];
else if(V[i][j]!=0&&V[i][i]!=0)
{
if((V[j][j]+V[i][j])<V[i][i])
V[i][i]=V[j][j]+V[i][j];
}
}
for(r=2; r<=k-1; r++)
for(i=a[r-2]+1; i<=a[r-1]; i++)
{
for(j=a[r-1]+1; j<=a[r]; j++)
if((V[i][i]-V[i][j])==V[j][j])
{
b[r]=j;
break;
}
i=j;
r++;
}
return V[1][1];
}
int main()
{
int i,j,r,sp;
createGraph();
b[1]=1;
b[k]=n;
//sp=Forward();
sp=Backward();
printf("最短路径长度为:%d\n",sp);
printf("最短路径为:");
printf("%d",b[1]);
for(i=2; i<=k; i++)
printf("->%d",b[i]);
return 0;
}
运行结果
向后求解法:
向后求解法:
多段图:
相关数据:
1 2 9
1 3 7
1 4 3
1 5 2
2 6 4
2 7 2
2 8 1
3 6 2
3 7 7
4 8 11
5 7 11
5 8 8
6 9 6
6 10 5
7 9 4
7 10 3
8 10 5
8 11 6
9 12 4
10 12 2
11 12 5