最小费用最大网络流
Posted mltang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小费用最大网络流相关的知识,希望对你有一定的参考价值。
先贴一个dalao的链接
https://blog.csdn.net/stillxjy/article/details/52047189
其实我个人认为最大网络流就是在不断的尝试加入新的增广路
每条增广路都有一定的权值
每次找的增光路是权值最小的,所以凑出了最小费用
证明的话,我也不是很会,脑补出来感觉是对的
#include <iostream> #include <queue> #include <vector> #include <cstdio> #include <string> #include <cstring> using namespace std; const int maxn = 5005; const int inf = 1e9; struct edge { int from,to,cost,c,f; }; vector<edge> e; vector<int> G[maxn]; void adde(int from,int to,int cost,int c,int f); bool spfa(int s,int t,int &f,int &cost); int main() { int n,m,s,t; scanf("%d%d%d%d",&n,&m,&s,&t); for(int i =0 ; i < m; ++i) { int from,to,c,w; scanf("%d%d%d%d",&from,&to,&c,&w); adde(from, to, w, c, 0); } int flow=0,cost=0; while(spfa(s, t, flow,cost)); printf("%d %d\n",flow,cost); } void adde(int from,int to,int cost,int c,int f) { edge a; a.from = from; a.to = to; a.cost = cost; a.c = c; a.f = 0; e.push_back(a); swap(a.from,a.to); a.cost = -a.cost; a.c = 0; e.push_back(a); int cnt = e.size(); G[from].push_back(cnt-2); G[to].push_back(cnt-1); } bool spfa(int s,int t,int &f,int &cost) { int dis[maxn]; bool inq[maxn]; int p[maxn]; int a[maxn]; memset(inq, false, sizeof(inq)); memset(a, 0, sizeof(a)); memset(p, 0, sizeof(p)); for(int i=0;i<maxn;++i) { dis[i] = inf; } queue<int> q; q.push(s); inq[s] = true; dis[s] = 0; a[s] = inf; while(!q.empty()) { int u = q.front(),i; inq[u] = false; q.pop(); for(i=0;i<G[u].size();++i) { edge l; l = e[G[u][i]]; if(dis[l.to] > dis[u]+l.cost && l.c>l.f) { p[l.to] = G[u][i]; a[l.to] = min(a[u],l.c - l.f); dis[l.to] = dis[u] + l.cost; if(!inq[l.to]) { inq[l.to] = true; q.push(l.to); } } } } if(dis[t] == inf) return false; f += a[t]; cost += a[t]*dis[t]; int u = t; while(u != s) { e[p[u]].f += a[t]; e[p[u]^1].f -= a[t]; u = e[p[u]].from; } return true; }
以上是关于最小费用最大网络流的主要内容,如果未能解决你的问题,请参考以下文章