网络流与费用流(下)费用流

来源:互联网 发布:退出淘宝客 之前的链接 编辑:程序博客网 时间:2024/05/16 17:45

费用流


费用流算法

好像有好多高级算法的样子,但我现在只会一个最简单的spfa连续最短路增广,这个东西就是贪心啦,最短路使每次增广的流的费用最小,没啥好说的。
针对这个做法,要注意的地方是,无向图每条边要建4条边。。。还有如果费用有负值要加判负环,别的也没什么了,算法是比较脑残的,关键是建图。
const int maxn=1010;const int maxm=50010;const int INF=0x3f3f3f3f;struct edge{int v,w,c,next;}e[maxm];int h[maxn],ecnt;inline void addedge(int u,int v,int w,int c){e[ecnt].v=v;e[ecnt].w=w;e[ecnt].c=c;e[ecnt].next=h[u];h[u]=ecnt++;}inline void Addedge(int u,int v,int w,int c){addedge(u,v,w,c);addedge(v,u,0,-c);addedge(v,u,w,c);//undirectedaddedge(u,v,0,-c);}int dis[maxn],pre[maxn],peg[maxn];bool vis[maxn];int flow,cost;bool spfa(int s,int t){clr(vis,0);clr(pre,-1);clr(dis,0x3f);queue<int> q;q.push(s);vis[s]=1;dis[s]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=h[u];~i;i=e[i].next){int v=e[i].v;if(e[i].w && dis[u]+e[i].c<dis[v]){dis[v]=dis[u]+e[i].c;pre[v]=u;peg[v]=i;if(!vis[v])q.push(v);vis[v]=1;}}}if(dis[t]==INF)return 0;return 1;}void mincostflow(int s,int t){flow=cost=0;while(spfa(s,t)){int mf=INF;for(int u=t;~pre[u];u=pre[u])mf=min(mf,e[peg[u]].w);for(int u=t;~pre[u];u=pre[u]){e[peg[u]].w-=mf;e[peg[u]^1].w+=mf;}flow+=mf;cost+=mf*dis[t];}}
其他方法留坑待填。。。

最大费用最大流

就是把所有边的费用取相反数然后求得的费用再取反。。。不过要注意原图有没有环,有环就不能用上面的算法来求了,这种情况暂时不会做。。。


有容量下限的最小费用最大流,留坑待填。。。


0 0
原创粉丝点击