EK最小費用最大流
阿新 • • 發佈:2021-11-01
最小費用最大流
這裡只給出程式碼實現:
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; } };