多源最短路floyd算法

著名的单源最短路算法有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;
}

posted @ 2011-08-23 11:08  Orig  阅读(417)  评论(0编辑  收藏  举报