最小费用最大流模板
来源:互联网 发布:mem 知乎 编辑:程序博客网 时间:2024/06/10 12:35
#include<bits/stdc++.h>#define ll long long#define inf 0x3f3f3f3fusing namespace std;const int MAXN=110;const int MAXM=100010;int head[MAXN],pre[MAXN],dis[MAXN],book[MAXN];int cnt=0,N;//N为点数 struct node{int to,next,cap,flow,cost;}edge[MAXM];void init(){cnt=0;memset(head,-1,sizeof(head));}void addedge(int u,int v,int cap,int cost){edge[cnt].to=v;edge[cnt].cap=cap;edge[cnt].flow=0;edge[cnt].cost=cost;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].cap=0;edge[cnt].flow=0;edge[cnt].cost=-cost;edge[cnt].next=head[v];head[v]=cnt++;}bool spfa(int s,int t){queue<int>q;while(!q.empty())q.pop();for(int i=0;i<=N;i++){dis[i]=inf;pre[i]=-1;book[i]=0;}dis[s]=0;book[s]=1;q.push(s);while(!q.empty()){int u=q.front();q.pop();book[u]=0;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(!book[v]){book[v]=1;q.push(v);}} } }return pre[t]!=-1;}int min_cost_max_flow(int s,int t,int &cost){int flow=0;cost=0;while(spfa(s,t)){int temp=inf;for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])temp=min(temp,edge[i].cap-edge[i].flow);for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){edge[i].flow+=temp;edge[i^1].flow-=temp;cost+=edge[i].cost*temp;}flow+=temp;}return flow;}
上面是自己写的,下面是从网上扒的用结构体封装好的。
#include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define N 1000#define INF 100000000struct Edge{ int from,to,cap,flow,cost; Edge(int u,int v,int ca,int f,int co):from(u),to(v),cap(ca),flow(f),cost(co){};};struct MCMF{ int n,m,s,t; vector<Edge> edges; vector<int> G[N]; int inq[N];//是否在队列中 int d[N];//距离 int p[N];//上一条弧 int a[N];//可改进量 void init(int n)//初始化 { this->n=n; for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } void addedge(int from,int to,int cap,int cost)//加边 { edges.push_back(Edge(from,to,cap,0,cost)); edges.push_back(Edge(to,from,0,0,-cost)); int m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool SPFA(int s,int t,int &flow,int &cost)//寻找最小费用的增广路,使用引用同时修改原flow,cost { for(int i=0;i<n;i++) d[i]=INF; memset(inq,0,sizeof(inq)); d[s]=0;inq[s]=1;p[s]=0;a[s]=INF; queue<int> Q; Q.push(s); while(!Q.empty()) { int u=Q.front(); Q.pop(); inq[u]--; for(int i=0;i<G[u].size();i++) { Edge& e=edges[G[u][i]]; if(e.cap>e.flow && d[e.to]>d[u]+e.cost)//满足可增广且可变短 { d[e.to]=d[u]+e.cost; p[e.to]=G[u][i]; a[e.to]=min(a[u],e.cap-e.flow); if(!inq[e.to]) { inq[e.to]++; Q.push(e.to); } } } } if(d[t]==INF) return false;//汇点不可达则退出 flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s)//更新正向边和反向边 { edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; u=edges[p[u]].from; } return true; } int MincotMaxflow(int s,int t) { int flow=0,cost=0; while(SPFA(s,t,flow,cost)); return cost; }};int main(){ MCMF mcmf; return 0;}
0 0
- 模板[最小费用最大流]
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流,模板
- 最小费用最大流模板
- 最小费用最大流 模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 双系统 ubuntu 16.04 和 win 10 时间同步问题
- 测试
- 链式栈的类定义
- 3多线程断点下载一个文件(android工程:java实现)
- Qt中路径问题小结
- 最小费用最大流模板
- 我上辈子欠你的
- JS学习随笔
- 注解(Annotation)注解处理器
- 我怎么这么幸运
- Spring容器初始化过程都做了哪些事儿
- Linux开发基础(1):开发板的挂载
- SHFileOperation()的外壳函数,用它可以实现各种文件操作,如文件的拷贝、删除、移动等
- 查找 关键字 是否在lib中