EK最小费用最大流
最小费用最大流
这里只给出代码实现:
class flow_map
{
private:
int u;
int s,t;
int n,m;
inline bool spfa()
{
memset(vis,0,sizeof(vis)),memset(dis,0x3f,sizeof(dis));
queue<int> q;
while(!q.empty()) q.pop();
dis[s]=0,vis[s]=1,q.push(s),incf[s]=0x3f3f3f3f;
register int u;
while(!q.empty())
{
u=q.front(),q.pop(),vis[u]=0;
for(register int j(head[u]);j;j=nex[j])
{
if(!flow[j]) continue;
if(dis[to[j]]>dis[u]+cost[j])
{
dis[to[j]]=dis[u]+cost[j],
incf[to[j]]=min(incf[u],flow[j]),
pre[to[j]]=j;
if(!vis[to[j]]) vis[to[j]]=1,q.push(to[j]);
}
}
}
return (dis[t]!=1061109567);
}
inline int against_edge(int id)
{
if(id&1) return (id+1);
else return (id-1);
}
public:
int edge_num;
int to[maxm],head[maxn],nex[maxm],flow[maxm],cost[maxm];
int dis[maxn];
bool vis[maxn];
int incf[maxn];
int pre[maxn];
int max_flow;
inline void set()
{
read_(n),
read_(m),
read_(s),
read_(t);
}
inline void add_edge(void)
{
++edge_num,
read_(u),read_(to[edge_num]),
read_(flow[edge_num]),
read_(cost[edge_num]),
nex[edge_num]=head[u],
head[u]=edge_num;
}
inline void add_edge(int u,int v,int f,int c)
{
to[++edge_num]=v,
nex[edge_num]=head[u],
head[u]=edge_num,
cost[edge_num]=c,
flow[edge_num]=f;
}
inline void build()
{
for(register int i(0),u,v,w,c;i<m;++i)
read_(u),
read_(v),
read_(w),
read_(c),
add_edge(u,v,w,c),
add_edge(v,u,0,-c);
}
inline int max_flow__min_cost()
{
register int mxf(0),mic(0),x;
while(spfa())
{
mxf+=incf[x=t],
mic+=incf[t]*dis[t];
while(x!=s)
flow[pre[x]]-=incf[t],
flow[against_edge(pre[x])]+=incf[t],
x=to[against_edge(pre[x])];
}
return max_flow=mxf,mic;
}
};