[图论]用Edmonds-Karp算法求解最大流问题(C语言实现)

Edmonds-Karp是求解最大流的一种算法,其他还有Ford-Fulkerson算法,这个算法在《算法导论》中有详细的介绍。下面我们来探讨下Edmonds-Karp算法。
Edmonds-Karp算法是利用一种动态规划的思想的算法。其主要用来解决下面这种最大流问题。[图论]用Edmonds-Karp算法求解最大流问题(C语言实现)_第1张图片

下面给出其具体的算法描述。
[图论]用Edmonds-Karp算法求解最大流问题(C语言实现)_第2张图片
其时间复杂度与选取的最短路径算法有直接的关系,它的复杂度为O(VE^2)(笔者不会证明这个结论,结论参考自:参考资料)。

下面给出C语言实现。

#include<stdio.h>
int n,matrix[100][100],ini,tre,i,j,st[100][100],tzq[100][100];//tzq调整权网络的构造! 
   void inputmatrix()
   {
    printf("请输入邻接矩阵的阶数:\n");
    scanf("%d",&n); 
    printf("请输入有向图的容量矩阵:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
           scanf("%d",&matrix[i][j]);//该矩阵不动,用于判断! 
    }   
    printf("请输入需计算的起始点下标:\n");
    scanf("%d",&ini);   
    printf("请输入需计算的终点下标:\n");
    scanf("%d",&tre);   
  } 
    //构造调整权网络
 void tzqnet()
 {
    for(i=0;i<n;i++)
       for(j=0;j<n;j++)
       {
        if(matrix[i][j]!=0){
            tzq[i][j]=matrix[i][j]-st[i][j];
            tzq[j][i]=st[i][j];
       }}
 }
   int prim(int a[100][100])
   {
    int k=n-1,t=0,t1,t2,min,j,m=1,w,flag=0;/*k,k1作为循环的次数,flag=1意味着可以继续循环,flag=0,跳出*/
    int E[100]={0};
    int distance[100]={0};
    int path[100][100]={0};
    E[ini-1]=1;
    path[ini-1][0]=ini;  
    while(k--)
    {
        min=100000;
        flag=0;// 初始化 
        for(j=0;j<n;j++)
        {
            for(i=0;i<n;i++) 
              if(E[i]==1&&E[j]==0&&min>(a[i][j]+distance[i])&&a[i][j]>0) /*寻找符合条件的数*/
              {
                flag=1;// 标记为1,找到!继续循环 
                t1=j;
                t2=i;
                min=a[i][j]+distance[i]; 
              }
        }
        if(flag==0)
            break;//跳出 
        distance[t1]=min;
        E[t1]=1;   /*标记为1,代表已经用过*/

        for(j=0;j<n;j++)//把t2的值加给t1,并且最后加上t1该点 
        {
                if(path[t2][j]!=0)
                {
                    path[t1][j]=path[t2][j];
                }   
                else
                {
                    path[t1][j]=t1+1;
                    break;
                }
        }
    }
    if(E[tre-1]==1)//存在最短路,下面进行增广 
    {
        //求得最小值
        int zgz=a[path[tre-1][0]-1][path[tre-1][1]-1];
        for(j=1;j<n;j++)
        {       
           if(path[tre-1][j]!=0)
             {
                if(zgz>a[path[tre-1][j-1]-1][path[tre-1][j]-1])
                  zgz=a[path[tre-1][j-1]-1][path[tre-1][j]-1];
             }
           else break;
        }   
        //增广 
        for(j=1;j<n;j++)
        {
           if(path[tre-1][j]!=0)
            {
                if(matrix[path[tre-1][j-1]-1][path[tre-1][j]-1]!=0)//正向+ 
                     st[path[tre-1][j-1]-1][path[tre-1][j]-1]+=zgz;
                else if(matrix[path[tre-1][j]-1][path[tre-1][j-1]-1]!=0)///fan向- 
                      st[path[tre-1][j]-1][path[tre-1][j-1]-1]-=zgz;
            }
            else break;
        }
    return 1;     
   }
    else
    return 0;
}
   main()
   {
      inputmatrix();
      tzqnet();//构造调整权网络 
      while(prim(tzq))//调用prim算法,并且判断是否继续运行! 
            tzqnet();   
   printf("\n\n---------得到最大流的矩阵形式如下----------\n\n");
    for(i=0;i<n;i++)
     {
        for(j=0;j<n;j++)
        {
            printf("%d ",st[i][j]);
        }   
        printf("\n");
     }     
    system("pause"); 
   }

[图论]用Edmonds-Karp算法求解最大流问题(C语言实现)_第3张图片

你可能感兴趣的:(算法,图论,最大流,Edmonds)