Posted on 2012-05-01 18:02
lenohoo 阅读(129)
评论(0) 编辑 收藏 引用
在网络中,若每条边【
vi,vj】除容量c
ij外,还给一个数
aij,表示从
vi到
vj运输单位物资所需支付的费用,则问题便是寻找一个可行流{
fij},其流值为给定的数值
r*,并使总费用取最小值。这样的可行流称为最小费用流。最小费用流问题可用对应于线性规划的原始算法和对偶算法求解。例如,若对偶算法是:从各边流
fij=0和流值
r=0的最小费用流开始,如果
r<
r*,则采用以费用作边长求最短路径的方法寻找关于{fij}的增广链,把{fij}调整为流值r′(r<r′≤r*)的最小费用流,直到流值为r*为止。
MCF
#define re(i,n) for(int i=0;i<n;i++)
#define MAXN 1001
#define MAXM 40010
#define inf (1<<29)
int N,M,pre[MAXM],first[MAXN],dist[MAXN];
bool vi[MAXN];
struct Edge{
int u,v,f,c,next;
}e[MAXM];
inline void _add(int u,int v,int f,int c){
e[M].u=u;e[M].v=v;e[M].f=f;e[M].c=c;
e[M].next=first[u];first[u]=M++;
}
inline void add(int u,int v,int f,int c){
_add(u,v,f,c);_add(v,u,0,-c);
}
inline bool spfa(int s,int t){
queue<int> Q;
re(i,N) dist[i]=inf,vi[i]=0,pre[i]=-1;
dist[s]=0;vi[s]=1;Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();vi[u]=0;
for(int i=first[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(e[i].f && dist[u]+e[i].c<dist[v]){
dist[v]=dist[u]+e[i].c;
pre[v]=i;
if(!vi[v]) { Q.push(v);vi[v]=1; }
}
}
}
return dist[t]!=inf;
}
int MCF(int s,int t){
int sum=0;
N+=2;
while(spfa(s,t)) {
sum+=dist[t];
int delta=inf;
for(int i=pre[t];i!=-1;i=pre[e[i].u])
delta=min(delta,e[i].f);
for(int i=pre[t];i!=-1;i=pre[e[i].u]) //easy wrong
e[i].f-=delta,e[i^1].f+=delta;
}
return sum;
}