著名的单源最短路算法有bellmanford(适合有负权边的图),以及dijkstra算法,dijkstra算法的算法是基于贪心算法的,i 与j之间的最短路基于表达式minlen[i][j]=min(minlen[i][j],min[i][k]+min[k][j]),其中k为中间结点 并且是已经被扫描过的结点,开始的时候只有已扫描集合中只有源结点,初始化min[i][k]=mat[i][k](如果是无向图,则mat[i] [j]=mat[j][i]),然后根据上述的贪心表达式依次求出,直到所有结点都被扫描到了。
基于单源最短路,多源最短路的朴素算法是对每个结点进行一次单源最短路计算,最后将结果保存在数组中。归纳一下,就是floyd多源最短路的朴素算法就是进行结点个数次dijkstra或者bellmanford就可以了。
作为例程:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=82
#include<stdio.h>
int mini[100][100],mat[100][100],n,m;
void floyd_warshall()
{
int i,j,k;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
mini[i][j]=mat[i][j];
for (k=0;k<n;k++)
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (mini[i][k]+mini[k][j]<mini[i][j])
mini[i][j]=mini[i][k]+mini[k][j];
}
int main()
{
int i,j,a,b,t,maxx,maxi,all,k;
bool flag;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
flag=false;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(i==j) mat[i][j]=0;
else mat[i][j]=100000000;
}
t=0;
k=n;
while(k--)
{
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
mat[t][a-1]=b;
}
t++;
}
floyd_warshall();
/* for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%d ",mini[i][j]);
printf("\n");
}
*/
for(i=0;j<n;j++)
{
for(j=0;j<n;j++)
if(mini[i][j]==100000000&&mini[j][i]==100000000) flag=true;
if(flag) break;
}
if(flag) {printf(" disjoint \n");continue;}
maxx=100000000;
for(i=0;i<n;i++)
{
all=0;
for(j=0;j<n;j++)
all+=mini[i][j];
if(all<maxx) {maxi=i;maxx=all;}
}
maxx=0;
for(j=0;j<n;j++)
if(mini[maxi][j]>maxx) maxx=mini[maxi][j];
printf("%d %d\n",maxi+1,maxx);
}
return 0;
}