1. 程式人生 > >最小費用最大網絡流

最小費用最大網絡流

memset 嘗試 網絡流 using edge iostream 大網 add pac

先貼一個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; }

最小費用最大網絡流