最大流
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR( a , x ) memset ( a , x , sizeof (a) );
const int maxm=1005;
const int maxn=20;
const int inf = 0x3f3f3f3f;
struct Dinic
{
struct Edge
{
int v,w,next;
}edge[maxm*2];
int tol,head[maxn],dis[maxn];
void addEdge(int u,int v,int w)
{
edge[tol].v=v,edge[tol].w=w,edge[tol].next=head[u];head[u]=tol++;
edge[tol].v=u,edge[tol].w=0,edge[tol].next=head[v];head[v]=tol++;
}
void init()
{
tol=0;
CLR(head,-1);
}
bool bfs(int s,int t)
{
queue<int>q;
q.push(s);
CLR(dis,-1);
dis[s]=0;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if( dis[v]<0 && edge[i].w)
{
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[t]!=-1;
}
int dfs(int s,int t,int low)
{
int flow;
if(t==s) return low;
for(int i=head[s];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(edge[i].w && (dis[v]==dis[s]+1) &&
(flow = dfs(v,t,min(low,edge[i].w))))
{
edge[i].w -= flow;
edge[i^1].w += flow;
return flow;
}
}
return 0;
}
int maxFlow(int s,int t)
{
int ans=0,tmp;
while(bfs(s,t))
while(tmp=dfs(s,t,inf))
ans+=tmp;
return ans;
}
}DC;
使用例子:
int main()
{
int t,m,n,a,b,c;
// RE
scanf("%d",&t);
for(int te=1;te<=t;te++)
{
DC.init();
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
DC.addEdge(a,b,c);
}
printf("Case %d: %d\n",te,DC.maxFlow(1,n));
}
return 0;
}
费用流模板用结构体包装后内存占用稍大,如果有严格内存限制的话就拆开来,基本是kuangbin的
最小费用流
求最大费用只需要取相反数,结果取相反数即可
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR( a , x ) memset ( a , x , sizeof (a) );
const int maxn = 200006;
const int maxm = 100006;
const int inf = 0x3f3f3f3f;
struct minCostDinic {
struct Edge {
int to, next, cap, flow, cost;
} edge[maxm * 2];
int head[maxn], tol;
int pre[maxn], dis[maxn];
bool vis[maxn];
void init() {
tol = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int cap, int cost) {
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = 0;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = 0;
edge[tol].cost = -cost;
edge[tol].flow = 0;
edge[tol].next = head[v];
head[v] = tol++;
}
bool spfa(int s, int t) {
queue<int>q;
memset(dis, inf, sizeof(dis));
memset(vis, false, sizeof(vis));
memset(pre, -1, sizeof(pre));
dis[s] = 0;
vis[s] = true;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (edge[i].cap > edge[i].flow &&
dis[v] > dis[u] + edge[i].cost ) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
}
return pre[t] != -1;
}
//返回最大流,cost存最小费用
int minCostMaxflow(int s, int t, int &cost) {
int flow = 0;
cost = 0;
while (spfa(s, t)) {
int Min = inf;
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) {
if (Min > edge[i].cap - edge[i].flow) {
Min = edge[i].cap - edge[i].flow;
}
}
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) {
edge[i].flow += Min;
edge[i ^ 1].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
}
} costDC;