弗洛伊德算法(Floyd)
此算法可以求任意两点的最短距离,其中边权值可以为负数,而dijkstra只能是固定的点间的距离,并且边全值不能为负数。
保存的是后面的点(更好)
#include<iostream>
#include<stdio.h>
#include<iomanip>
using namespace std;
#define N 100
#define MAX 1000000
int a[N][N];
int path[N][N];
void input (int n)
{
int p,q,len,i,j;
for( i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
a[i][j]=MAX;
if(i==j)
a[i][j]=0;
}
while(1)
{
cin>>p>>q;
if(p||q)
cin>>len;
else
break;
a[p][q]=len;
}
}
void Floyd(int n)
{
int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
path[i][j]=j;//初始化路径,将i后面的点记录在path中
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][j]>a[i][k]+a[k][j])
{
a[i][j]=a[i][k]+a[k][j];
path[i][j]=path[i][k];/*path记录i后面的点*/
}
printf("最短路径矩阵如下:\n");
for(i=1;i<=n;i++)/*打印最短路径矩阵j*/
{
for(j=1;j<=n;j++)
printf("%8d",a[i][j]);
cout<<endl;
}
}
void Dispath(int n)//输出经过的点
{
int i,j,h;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
cout<<" 经过的点为: ";
cout<<i<<"->";
h=path[i][j];
while(h!=j)
{
cout<<h<<"->";
h=path[h][j];
}
cout<<j<<endl;
}
}
int main()
{
int n;
scanf("%d",&n);
input(n);
Floyd(n);
Dispath(n);
return 0;
}
或者
保存的是前面的点
#include<iostream>
#include<stdio.h>
#include<iomanip>
using namespace std;
#define N 100
#define MAX 10000
int a[N][N];
int path[N][N];
void input (int n)
{
int p,q,len,i,j;
for( i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
a[i][j]=MAX;
if(i==j)
a[i][j]=0;
}
while(1)
{
cin>>p>>q;
if(p||q)
cin>>len;
else
break;
a[p][q]=len;
}
}
void Floyd(int n)
{
int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
path[i][j]=i;//初始化路径,将j前面的点记录在path中
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][j]>a[i][k]+a[k][j])
{
a[i][j]=a[i][k]+a[k][j];
path[i][j]=path[k][j];/*path记录j前面的点*/
}
printf("最短路径矩阵如下:\n");
for(i=1;i<=n;i++)/*打印最短路径矩阵*/
{
for(j=1;j<=n;j++)
printf("%8d",a[i][j]);
cout<<endl;
}
}
void Dispath(int n)//输出经过的点
{
int i,j,temp,que[N],tot;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
tot=1;
que[tot++]=j;
temp=path[i][j];
while(temp!=i)
{
que[tot++]=temp;
temp=path[i][temp];
}
que[tot]=i;
cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
cout<<" 经过的点为: ";
for(;tot>1;tot--)
cout<<que[tot]<<"->";
cout<<que[tot]<<endl;
}
}
int main()
{
int n;
scanf("%d",&n);
input(n);
Floyd(n);
Dispath(n);
return 0;
}
递归也可以
#include<iostream>
#include<stdio.h>
#include<iomanip>
using namespace std;
#define N 100
#define MAX 10000
int a[N][N];
int path[N][N];
void input (int n)
{
int p,q,len,i,j;
for( i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
a[i][j]=MAX;
if(i==j)
a[i][j]=0;
}
while(1)
{
cin>>p>>q;
if(p||q)
cin>>len;
else
break;
a[p][q]=len;
}
}
void Floyd(int n)
{
int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
path[i][j]=-1;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][j]>a[i][k]+a[k][j])
{
a[i][j]=a[i][k]+a[k][j];
path[i][j]=k;
}
printf("最短路径矩阵如下:\n");
for(i=1;i<=n;i++)/*打印最短路径矩阵*/
{
for(j=1;j<=n;j++)
printf("%8d",a[i][j]);
cout<<endl;
}
}
void ppath(int i,int j)//递归你懂吗
{
int k;
k=path[i][j];
if(k==-1)
return;
ppath(i,k);
printf("->%d",k);
ppath(k,j);
}
void Dispath(int n)//输出经过的点
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cout<<" 点 "<<i<<" 到点 "<<j<<" 最短长度为: "<<a[i][j];
cout<<" 经过的点为: ";
cout<<i;
ppath(i,j);
cout<<"->"<<j;
cout<<endl;
}
}
int main()
{
int n;
scanf("%d",&n);
input(n);
Floyd(n);
Dispath(n);
return 0;
}