基于BellmanFord求最短路的最小费用流模板
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 const int maxn=205; 8 const int inf=1e9; 9 struct edge{ 10 int from,to,flow,cost; 11 edge(int u,int v,int f,int c):from(u),to(v),flow(f),cost(c) {} 12 }; 13 int n,s,t; 14 long long cost; 15 vector<edge>E; 16 vector<int>G[maxn]; 17 bool vis[maxn]; 18 int d[maxn],p[maxn],a[maxn]; //d为最短距离(相当于最少费用),p用于存储该点的前一条边,a用于求流量 19 20 void init() 21 { 22 for ( int i=0;i<=n;i++ ) G[i].clear(); 23 E.clear(); 24 } 25 26 void addedge(int u,int v,int f,int c) 27 { 28 E.push_back(edge(u,v,f,c)); 29 E.push_back(edge(v,u,0,-c)); 30 int m=E.size(); 31 G[u].push_back(m-2); 32 G[v].push_back(m-1); 33 } 34 35 bool bellmanford(int& flow) 36 { 37 for ( int i=0;i<=n;i++ ) d[i]=inf; 38 memset(vis,false,sizeof(vis)); 39 d[s]=0; 40 vis[s]=true; 41 p[s]=0; 42 a[s]=inf; 43 queue<int>que; 44 que.push(s); 45 while ( !que.empty() ) { 46 int u=que.front(); 47 que.pop(); 48 vis[u]=false; 49 for ( int i=0;i<G[u].size();i++ ) { 50 edge& e=E[G[u][i]]; 51 if ( e.flow>0 && d[e.to]>d[u]+e.cost ) { 52 d[e.to]=d[u]+e.cost; 53 p[e.to]=G[u][i]; 54 a[e.to]=min(a[u],e.flow); 55 if ( !vis[e.to] ) { 56 que.push(e.to); 57 vis[e.to]=true; 58 } 59 } 60 } 61 } 62 if ( d[t]==inf ) return false; 63 flow+=a[t]; 64 cost+=(long long)d[t]*(long long)a[t]; 65 for ( int u=t;u!=s;u=E[p[u]].from ) { 66 E[p[u]].flow-=a[t]; 67 E[p[u]^1].flow+=a[t]; 68 } 69 return true; 70 } 71 72 //需要保证初始网络种没有负权图 73 int mincost() 74 { 75 int flow=0; 76 cost=0; 77 while ( bellmanford(flow)); 78 return flow; 79 } 80 81 最小费用流