网络流--最小费用最大流MCMF模板

时间:2023-03-10 03:44:14
网络流--最小费用最大流MCMF模板

标准大白书式模板

 #include<stdio.h>        //大概这么多头文件昂
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxm=+; //最大点数
const int INF=0x3f3f3f3f; struct edge{ //边:起点、终点、容量、流量、单位费用
int from,to,c,f,cost;
edge(int a,int b,int m,int n,int p):from(a),to(b),c(m),f(n),cost(p){}
}; int aabs(int a){
return a>=?a:-a;
} struct MCMF{
int m,s,t;
vector<edge>e;
vector<int>g[maxm];
int dis[maxm],a[maxm],p[maxm];
bool vis[maxm]; void init(int n){ //初始化函数
for(int i=;i<=n;i++)g[i].clear();
e.clear();
} void add(int a,int b,int c,int v){ //加边函数
e.push_back(edge(a,b,c,,v));
e.push_back(edge(b,a,,,-v));
m=e.size();
g[a].push_back(m-);
g[b].push_back(m-);
} bool spfa(int& flow,int& cost){
memset(dis,0x3f,sizeof(dis));
memset(vis,,sizeof(vis));
queue<int>q;
q.push(s);
vis[s]=;
dis[s]=;
p[s]=;
a[s]=INF;
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=;
for(int i=;i<g[u].size();i++){
edge tmp=e[g[u][i]];
if(dis[tmp.to]>dis[u]+tmp.cost&&tmp.c>tmp.f){
dis[tmp.to]=dis[u]+tmp.cost;
p[tmp.to]=g[u][i];
a[tmp.to]=min(a[u],tmp.c-tmp.f);
if(!vis[tmp.to]){
q.push(tmp.to);
vis[tmp.to]=;
}
}
}
}
if(dis[t]==INF)return ;
flow+=a[t];
cost+=dis[t]*a[t];
int u=t;
while(u!=s){
e[p[u]].f+=a[t];
e[p[u]^].f-=a[t];
u=e[p[u]].from;
}
return ;
} int MF(int s,int t){ 调用的计算最小费用函数
this->s=s;this->t=t;
int flow=,cost=;
while(spfa(flow,cost));
return cost;
} };