1. 程式人生 > >最小費用最大流(spfa增廣)——模板整理

最小費用最大流(spfa增廣)——模板整理

這個演算法好像沒名字。。就是每次spfa增廣。
時間複雜度O(n*m^2*3)?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=5005,maxe=100005;
int n,m,nxt[maxe],S,T,fir[maxn],tot=1,f[maxn],dis[maxn],path[maxn],ans1,ans2;
struct Edge { int from,to,cap,flow,cost; } Es[maxe];
queue
<int>
que; bool vis[maxn]; void add(int x,int y,int w,int c){ Es[++tot]=(Edge){x,y,w,0,c}; nxt[tot]=fir[x]; fir[x]=tot; Es[++tot]=(Edge){y,x,0,0,-c}; nxt[tot]=fir[y]; fir[y]=tot; } bool Find_SPFA(int s,int t,int &MaxFlow,int &MinCost){ memset(f,0,sizeof(f)); f[s]=1e+9
; memset(dis,63,sizeof(dis)); dis[s]=0; memset(vis,0,sizeof(vis)); while(!que.empty()) que.pop(); que.push(s); while(!que.empty()){ int x=que.front(); que.pop(); vis[x]=false; for(int j=fir[x];j;j=nxt[j]){ if(Es[j].cap>Es[j].flow&&dis[x]+Es[j].cost<dis[Es[j].to]){ dis[Es[j].to]=dis[x]+Es[j].cost; path[Es[j].to]=j; f[Es[j].to]=min(f[x],Es[j].cap-Es[j].flow); if
(!vis[Es[j].to]) vis[Es[j].to]=true, que.push(Es[j].to); } } } if(!f[t]) return false; MaxFlow+=f[t]; MinCost+=f[t]*dis[t]; for(int i=t;i!=s;i=Es[path[i]].from){ Es[path[i]].flow+=f[t]; Es[path[i]^1].flow-=f[t]; } return true; } int main(){ scanf("%d%d%d%d",&n,&m,&S,&T); for(int i=1;i<=m;i++){ int x,y,z,c; scanf("%d%d%d%d",&x,&y,&z,&c); add(x,y,z,c); } ans1=ans2=0; while(Find_SPFA(S,T,ans1,ans2)); printf("%d %d\n",ans1,ans2); return 0; }