最小费用最大流
#include<bits/stdc++.h> using namespace std; //假设无平行边和a-b b-a的回路,cost可以是负值 //利用bellmanford算法求最短路径,因为需要最小cost //这个算法支持中途调用,但是调用时必须是最小cost状态,因为dp const int maxn=1001; int G[maxn][maxn],pre[maxn],n,m,flow[maxn][maxn],d[maxn],w[maxn][maxn],cost=0,as[maxn];//flow是当前的流量 a 代表到某个点的最小残余流量 //通过前驱数组求一条路径,当然结果可能会多了不是这条路径上的点的前驱,因为不一定能一次到 int flg[maxn]; int max_flow_with_cost(int s,int t){ int f=0; memset(flow,0,sizeof(flow)); while(1){ queue<int> q; q.push(s); memset(flg,0,sizeof(flg)); memset(pre,0,sizeof(pre)); memset(d,0x3f3f3f3f,sizeof(d)); memset(as,0x3f3f3f3f,sizeof(as)); flg[s]=1; d[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); flg[x]=0;//用于标识队列中如果有了,不重复加入队列 for(int i=1;i<=n;i++){ if(G[x][i]!=0&&G[x][i]>flow[x][i]&&d[x]+w[x][i]<d[i]){ d[i]=d[x]+w[x][i]; pre[i]=x; // as[i]=min(as[i],G[x][i]-flow[x][i]); if(!flg[i]){ flg[i]=1; q.push(i); } } } } //t不可达即停止,当然也可以通过pre试试能不能到s然后停止,用a也可 if(d[t]==0x3f3f3f3f) {cout<<"cost is "<<cost<<endl; return f;} int a=0x3f3f3f3f; // a=as[t]; for(int i=t;pre[i]!=0;i=pre[i]) a=min(a,G[pre[i]][i]-flow[pre[i]][i]); for(int i=t;pre[i]!=0;i=pre[i]){ flow[pre[i]][i]+=a; flow[i][pre[i]]-=a; cost+=a*w[pre[i]][i]; } // cost+=a*d[t]; f+=a; } } int main() { cin>>n>>m; memset(G,0,sizeof(G)); for(int i=0;i<m;i++){ int x,y,z,k; cin>>x>>y>>z>>k; G[x][y]=z; w[x][y]=k; } cout<<max_flow_with_cost(1,2)<<endl; return 0; }