复杂度 O(n2m)。支持一边构建网络,一边求最大流。每次调用 flow(),得到当前新增的流量。

#include <iostream>

using namespace std;

const int maxn = 500 + 5
const int maxm = 100000 + 5
const int maxint = 0x7FFFFFFF

class network_c

public:
    
void init(int _n, int _s, int _t);
    
void add_edge(int u, int v, int _c, bool direct);
    
int flow();
private:
    
int n, s, t, m, first[maxn];
    
int c[maxm], f[maxm], p[maxm], next[maxm];
    
int queue[maxn], pre[maxn], change[maxn], edge[maxn];
}
;

void network_c::init(int _n,int _s,int _t)
{
    n 
= _n;
    s 
= _s;
    t 
= _t;
    m 
= 0;
    
for (int i = 1; i <= n; i++)
        first[i] 
= 0;
}


void network_c::add_edge(int u, int v, int _c, bool direct)
{
    m
++;
    c[m] 
= _c;
    f[m] 
= 0;
    p[m] 
= v;
    next[m] 
= first[u];
    first[u] 
= m;
    m
++;
    c[m] 
= direct ? 0 : _c;
    f[m] 
= 0;
    p[m] 
= u;
    next[m] 
= first[v];
    first[v] 
= m;
}


int network_c::flow()
{
    
int answer = 0, op;
    
while (1)
    
{
        
for (int i = 1; i <= n; i++)
            pre[i]
=0;
        pre[s] 
= s;
        
int op = 1;
        queue[op] 
= s;
        change[s] 
= maxint;
        
for (int cl = 1; cl <= op && pre[t] == 0; cl++)
        
{
            
int k = queue[cl];
            
for (int i = first[k]; i != 0; i = next[i])
                
if (f[i] < c[i] && pre[p[i]] == 0)
                
{
                    pre[p[i]] 
= k;
                    edge[p[i]] 
= i;
                    change[p[i]] 
= min(change[k], c[i] - f[i]);
                    queue[
++op] = p[i];
                }

        }

        
if (pre[t] == 0)
            
break;
        
int d = change[t];
        answer 
+= d;
        
for (int k = t; k != s; k = pre[k])
        
{
            f[edge[k]] 
+= d;
            f[((edge[k] 
- 1^ 1+ 1-= d;
        }

    }

    
return answer;
}
posted on 2007-08-13 21:12 Felicia 阅读(1004) 评论(1)  编辑 收藏 引用 所属分类: Felicia 的标程图论
Comments

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理