最小费用最大流模板
来源:互联网 发布:平面设计师 美工招聘 编辑:程序博客网 时间:2024/05/29 18:32
/*最小费用最大流的模型在保证流量最大的前提下,所需的费用最小,这就是最小费用最大流问题.基本思路: 把弧<u,v>的单位费用c看作弧<u,v>的路径长度,每次找从源点s到汇点t长度最短(费用最小)的可增广路径进行增广。1. 最小费用可增广路2. 路径s到t的长度即[单位流量]的费用。ps:是网络流EK算法的改进,在求增广路径的时候,spfa每次求权值最小的增广路。ps:要注意一点,逆边cost[i][j] = -cost[j][i],不能忘了加上去。*///#include<bits/stdc++.h>#include <cstdio>#include <cstdlib>#include <iostream>#include <cstring>#include <string>#include <vector>#include <cmath>#include <map>#include <queue>#include <stack>#include <set>#include <algorithm>using namespace std;#define For(i,a,b) for(int (i)=(a);(i) < (b);(i)++)#define rof(i,a,b) for(int (i)=(a);(i) > (b);(i)--)#define IOS ios::sync_with_stdio(false)#define lson l,m,rt <<1#define rson m+1,r,rt<<1|1#define mem(a,b) memset(a,b,sizeof(a))typedef long long ll;typedef unsigned long long ull;void RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x;}void RII (int& x, int& y){RI (x), RI (y);}void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}/**************************************END define***************************************/const int maxn = 2e3+10;const int maxm = 2e4+10;const int INF =0x3f3f3f3f;struct Side{ int to,next,f,c;}side[maxm];//int flow;int cas, ans, top, n, m, s, t;int dis[maxn], pre[maxn], node[maxn];bool inqueue[maxn];queue<int> q;void add_side(int u,int v,int f,int c) //f是流量,c是单位流量的费用(当成路径长度){ side[top]=(Side){v,node[u],f,c};node[u]=top++; side[top]=(Side){u,node[v],0,-c};node[v]=top++;}bool spfa(){ memset(inqueue,0,sizeof(inqueue)); memset(dis,0x3f,sizeof(dis)); q.push(s); dis[s]=0; //inqueue[s]=true; pre[s]=-1; while(!q.empty())//通过spfa得到最短路径(最小花费)的增广路 { int u=q.front(); q.pop(); inqueue[u]=0; for(int i=node[u];i!=-1;i=side[i].next) { int v=side[i].to; if(dis[v]>dis[u]+side[i].c&&side[i].f>0) { //cout<<u<<" "<<v<<" "; dis[v]=dis[u]+side[i].c; pre[v]=i; //连接点v的前一条边 if(!inqueue[v]) { inqueue[v]=true; q.push(v); } } } } if (dis[t] == INF) return false; // 无增广路,结束 int aug=INF; for(int p=pre[t];p!=-1;p=pre[side[p^1].to]) aug=min(aug,side[p].f); //本条增广路的流量 for(int p=pre[t];p!=-1;p=pre[side[p^1].to]) { side[p].f -= aug; //路径中的边流量减掉aug side[p^1].f += aug; //反向边+aug } //flow+=aug; //最小费用最大流的流量和 ans += dis[t] * aug; //单位流量的花费*流量 return true;}int main(){ //freopen("in.txt","r",stdin); scanf("%d",&cas); while(cas--) { //flow=0; top=0; scanf("%d%d%d%d", &n, &m, &s, &t);//这里给源点汇点赋值 memset(node,-1,sizeof(node)); for(int i=0;i<m;i++) { int u,v,f,c; scanf("%d%d%d%d", &u, &v, &f, &c); add_side(u,v,f,c); } ans=0; while(spfa()); printf("%d\n",ans); //ans返回的是最小费用最大流的 权值和 //printf("flow=%d\n",flow ); //返回的是最小费用最大流的 总流量 } return 0;}http://paste.ubuntu.com/12197696/
0 0
- 模板[最小费用最大流]
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流,模板
- 最小费用最大流模板
- 最小费用最大流 模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- mysql-触发器
- UVA331
- CSS (二)解析CSS盒子
- 正则表达式快速入门
- yum源配置
- 最小费用最大流模板
- OC 面向对象里字典和集合的常用用法
- 第24周工作计划表
- HDOJ题目1052Tian Ji -- The Horse Racing(贪心)
- 华硕R510LD,win7显卡独显硬件驱动问题解决
- Linux命令:chgrp
- DOS循环:bat/批处理for命令详解之一 (史上虽详尽的总结和说明~~)
- BZOJ 1657: [Usaco2006 Mar]Mooo 奶牛的歌声
- 何为抽象?你有本末倒置吗?