最大流算法

同学们坐好,我说一下啊。
咱班那,咱班,总是有那么几个……好说之人!

纯属跑题哈!

最大流问题是一类应用极为广泛的问题,例如在交通运输
网络中有人流、车流、货物流、供水系统中有水流,金融

系统中有现金流,通信系统中有信息流,等等……

当然了,这些流是在管道中传输的,管道要有个直径,就是有个容积问题。进去多少水,就要出来多少。而且不能超过管子的直径。如果途中经过多个管子,那么就不能超过最细的管子的容积。

所以,网络流的最重要问题就是如何能把能灌满的管子尽量灌满,最后都流向汇点

从一个源点出发,用类似BFS搜索出汇点(两点间是否相邻取决于c[i][j]=0?)其中c表示残余容量,就是从I到J管子还能装多少。这样的路径就是增广路。

直到无法搜索出这样的路径,那么就算装Max了。

算法如下:

初始化;

对于每一条增广路径(怎么搜我不管)的每一条边

c[i][j]-=min{c[i`][j`]};这里肯定保证c[i][j]做完运算后>=0

c[j][i]+=min{c[i`][j`]};流抵消。从i到j运送了K,意味着从J到I就有了K的流量可以运送。

liu+=min{c[i`][j`]};记录下

次在s-t之间找出费用最小的一条路径即单源最短路,如果t点不再被访问到,则算法终止。否则,按着最短路径找出最小剩余容量c,最大流量加上c, 再更新最短路径上的边,前向弧减去c,反向弧加上c,并且造一条逆向的费用边,最小费用加上每条边的花销,每条边的花销=单位费用*c。

最小费用最大流既能求最小费用,又能得出最大流,是更为一般的模型。

 

 

牛人哈~~~自己也懒得看原理了,代码中使用了bellman-ford算法,貌似可以改进为spfa,会更好。

 

/**//**** **** **** **** **** ****
网络中最小费用最大流

const int NMAX = 210;
int net[NMAX][NMAX], cost[NMAX][NMAX];
int path[NMAX], ecost[NMAX];
int n;
bool bellman_ford()
{
    
int i,j;
     memset(path,
-1,sizeof(path));
     fill(ecost, ecost
+NMAX, INT_MAX);
     ecost[
0] = 0;

    
bool flag = true;
    
while(flag) {
         flag
= false;
        
for(i=0;i<=n;i++) {
            
if(ecost[i] == INT_MAX) {
                
continue ;
             }

            
for(j=0;j<=n;j++) {
                
if(net[i][j] > 0 && ecost[i]+cost[i][j] < ecost[j]) {
                     flag
= true;
                     ecost[j]
= ecost[i]+cost[i][j];
                     path[j]
= i;
                 }

             }

         }

     }

    
return ecost[n] != INT_MAX;
}


int min_cost_max_flow()
{
    
int i,j;
    
int mincost = 0, maxflow = 0;
    
while( bellman_ford() ) {
        
int now = n;
        
int neck = INT_MAX;
        
while(now != 0) {
            
int pre = path[now];
             neck
= min(neck, net[pre][now]);
             now
= pre;
         }

         maxflow
+= neck;
         now
= n;
        
while(now != 0) {
            
int pre = path[now];
             net[pre][now]
-= neck;
             net[now][pre]
+= neck;
             cost[now][pre]
= - cost[pre][now];
             mincost
+= cost[pre][now] * neck;
             now
= pre;
         }

     }

    
return mincost;
}

 

posted @ 2008-10-31 11:20  SЁv⑦ēЙ  阅读(428)  评论(0)    收藏  举报