最近正好需要用到最小费用最大流,所以网上就找了这方面的代码,动手写了写,先在博客里存一下~
代码的题目是POJ2135-Farm Tour
需要了解算法思想的,可以参考下面一篇文章,个人觉得有最大流基础的童鞋,看了基本就能看懂了,通俗易懂。
https://www.cnblogs.com/gtarcoder/p/4890739.html
#include <iostream> #include <string> #include <cmath> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #define E 50000 #define maxn 1005 #define INF 0x3f3f3f3f using namespace std; struct Edge { int u,v,flow,cost,next; }edge[E]; int tot,head[maxn],pre[maxn],dist[maxn],vis[maxn]; int n,m; void add(int u,int v,int flow,int cost)//flow为流量 cost为费用 { edge[tot].u=u; edge[tot].v=v; edge[tot].flow=flow; edge[tot].cost=cost; edge[tot].next=head[u]; head[u]=tot++; } void addEdge(int u,int v,int flow,int cost){ add(u,v,flow,cost); add(v,u,0,-cost); } bool SPFA(int s,int t,int n) { int v,tmp; queue<int> q; for(int i=0;i<=n;i++) { pre[i]=-1; vis[i]=0; dist[i]=INF; } vis[s]=1; dist[s]=0; q.push(s); while(!q.empty()) { tmp=q.front(); q.pop(); vis[tmp]=0; for(int k=head[tmp];k!=-1;k=edge[k].next) if(edge[k].flow){ v=edge[k].v; if(dist[v]>dist[tmp]+edge[k].cost){ dist[v]=dist[tmp]+edge[k].cost; pre[v]=k; //存储对应的边 if(!vis[v]){ vis[v]=1; q.push(v); } } } } return dist[t]!=INF; } int mcmf(int s,int t,int n) { int flow=INF,ans=0; while(SPFA(s,t,n)) { ans+=dist[t]; for(int k=pre[t];k!=-1;k=pre[edge[k].u]) flow=min(flow,edge[k].flow); for(int k=pre[t];k!=-1;k=pre[edge[k].u]) { edge[k].flow-=flow; edge[k^1].flow+=flow; } } return ans; } void init(){ for(int i=0;i<maxn;i++) head[i]=-1; tot=0; } int main() { int n,m; scanf("%d %d",&n,&m); int s=0,t=n+1; init(); for(int i=0;i<m;i++){ int u,v,c; scanf("%d %d %d",&u,&v,&c); addEdge(u,v,1,c); addEdge(v,u,1,c); } addEdge(s,1,2,0); addEdge(n,t,2,0); int ans=mcmf(s,t,n+1); printf("%d ",ans); return 0; }