多源最短路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;
}
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号