網路流(2)-----最小費用最大流
阿新 • • 發佈:2018-12-15
一.
二.
1.EK演算法 + SPFA 最短路
(1)程式碼:
#include <iostream> #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f const int maxn = 5000 + 7; struct Edge{ int from,to,next,cap,flow,cost; }edge[maxn*20]; int head[maxn],pre[maxn],dist[maxn],n,m,tot,s,t; bool vis[maxn]; void addEdge(int a,int b,int c,int cost){ edge[tot].from = a;edge[tot].to = b;edge[tot].next = head[a];edge[tot].cap = c;edge[tot].flow = 0;edge[tot].cost = cost;head[a] = tot++; edge[tot].from = b;edge[tot].to = a;edge[tot].next = head[b];edge[tot].cap = 0;edge[tot].flow = 0;edge[tot].cost = -cost;head[b] = tot++; } bool SPFA(){ memset(dist,INF,sizeof(dist)); memset(vis,0,sizeof(vis)); queue<int> que; dist[s] = 0; vis[s] = 1; que.push(s); while(!que.empty()){ int u = que.front(); que.pop(); vis[u] = 0; for(int i = head[u];~i;i = edge[i].next){ int v = edge[i].to; if(edge[i].cap > edge[i].flow && dist[v] > dist[u] + edge[i].cost){ dist[v] = dist[u] + edge[i].cost; pre[v] = i; if(!vis[v]){ vis[v] = 1; que.push(v); } } } } if(dist[t]!=INF)return true; return false; } int CostFlow(int &flow){ int mincost = 0; while(SPFA()){ int Min = INF; for(int i = t;i!=s;i = edge[pre[i]].from){ Min = min(Min,edge[pre[i]].cap - edge[pre[i]].flow); } for(int i = t;i!=s;i = edge[pre[i]].from){ edge[pre[i]].flow+=Min; edge[pre[i]^1].flow-=Min; } flow+=Min; mincost+=(dist[t]*Min); } return mincost; } int main() { int T; scanf("%d",&T); while(T--){ tot = 0; memset(head,-1,sizeof(head)); scanf("%d%d%d%d",&n,&m,&s,&t); for(int i = 0;i<m;i++){ int a,b,c,cost; scanf("%d%d%d%d",&a,&b,&c,&cost); addEdge(a,b,c,cost); } int MaxFlow = 0; int MinCost = CostFlow(MaxFlow); printf("%d %d\n",MaxFlow,MinCost); } return 0; }