最大流 最小费用流模板

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 const int INF = 0x3f3f3f3f;
 7 const int N = 10005;
 8 const int M = 100005;
 9 struct type{
10     int u, v, w, next;
11 }edge[M << 1];
12 int head[N], cnt;
13 int dep[N], cur[N];
14 int n, m, s, t, d;
15 void add(int x, int y, int z){
16     edge[cnt].u = x;
17     edge[cnt].v = y;
18     edge[cnt].w = z;
19     edge[cnt].next = head[x];
20     head[x] = cnt;
21     cnt++;
22 }
23 bool bfs(){
24     int fro = 0;
25     queue<int> q;
26     q.push(s);
27     for(int i = 1; i <= n; i++) dep[i] = 0;
28     dep[s] = 1;//important!!!!!
29     while(!q.empty()){
30         fro = q.front(); q.pop();
31         for(int i = head[fro]; i != -1; i = edge[i].next){
32             int vv = edge[i].v;
33             if(!dep[vv] && edge[i].w > 0){
34                 dep[vv] = dep[fro] + 1;
35                 q.push(vv);
36             }
37         }
38     }
39     return dep[t] ? 1 : 0;
40 }
41 int dfs(int x, int rest){
42     if(x == t || !rest) return rest;
43     for(int& i = cur[x]; i != -1; i = edge[i].next){//当前弧优化
44         int vv = edge[i].v, ww = edge[i].w;
45         if(dep[vv] != dep[x] + 1) continue;
46         d = dfs(vv, min(rest, ww));
47         if(d > 0){
48             edge[i].w -= d;
49             edge[i ^ 1].w += d;
50             return d;
51         }
52     }
53     return 0;
54 }
55 int dinic(){
56     int ans = 0;
57     while(bfs()){
58         for(int i = 1; i <= n; i++) cur[i] = head[i];//当前弧优化
59         if(d = dfs(s, INF)){
60             ans += d;
61         }
62     }
63     return ans;
64 }
65 int main() {
66     int x, y, z;
67     scanf("%d%d%d%d", &n, &m, &s, &t);
68     for(int i = 1; i <= n; i++) head[i] = -1;
69     for(int i = 1; i <= m; i++){
70         scanf("%d%d%d", &x, &y, &z);
71         add(x, y, z);
72         add(y, x, 0);
73     }
74     printf("%d", dinic());
75     return 0;
76 }

最大流dinic

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 const int INF = 0x3f3f3f3f;
 7 const int N = 5005;
 8 const int M = 50005;
 9 struct type{
10     int u, v, w, f, next;
11 }edge[M << 1];
12 struct type2{
13     int f, cur, incf;
14     bool vis;
15 }ser[N];
16 int head[N], cnt;
17 int n, m, s, t;
18 int max_flow, min_cost;
19 void add(int x, int y, int z, int zz){
20     edge[cnt].u = x;
21     edge[cnt].v = y;
22     edge[cnt].w = z;
23     edge[cnt].f = zz;
24     edge[cnt].next = head[x];
25     head[x] = cnt;
26     cnt++;
27 }
28 bool spfa(){
29     for(int i = 1; i <= n; i++){
30         ser[i].vis = 0;
31         ser[i].f = INF;
32     }
33     ser[s].f = 0;
34     ser[s].incf = INF;
35     int fro;
36     queue<int> q;
37     q.push(s);
38     while(!q.empty()){
39         fro = q.front(); q.pop(); ser[fro].vis = 0;
40         for(int i = head[fro]; i != -1; i = edge[i].next){
41             int vv = edge[i].v, ww = edge[i].w, ff = edge[i].f;
42             if(ww > 0 && ser[fro].f + ff < ser[vv].f){
43                 ser[vv].f = ser[fro].f + ff;
44                 ser[vv].incf = min(ser[fro].incf, ww);
45                 ser[vv].cur = i;
46                 if(!ser[vv].vis){
47                     ser[vv].vis = 1;
48                     q.push(vv);
49                 }
50             }
51         }
52     }
53     return ser[t].f == INF ? 0 : 1;
54 }
55 void update(){
56     int i = t, j;
57     while(i != s){
58         j = ser[i].cur;
59         edge[j].w -= ser[t].incf;
60         edge[j ^ 1].w += ser[t].incf;
61         i = edge[j].u;
62     }
63     max_flow += ser[t].incf;
64     min_cost += ser[t].f * ser[t].incf;
65 }
66 void EK(){
67     while(spfa()){
68         update();
69     }
70 }
71 int main() {
72     //freopen("testdata.in", "r", stdin);
73     //freopen("testdata.out", "w", stdout);
74     int x, y, z, zz;
75     scanf("%d%d%d%d", &n, &m, &s, &t);
76     for(int i = 1; i <= n; i++) head[i] = -1;
77     for(int i = 1; i <= m; i++){
78         scanf("%d%d%d%d", &x, &y, &z, &zz);
79         add(x, y, z, zz);
80         add(y, x, 0, -zz);
81     }
82     EK();
83     printf("%d %d\n", max_flow, min_cost);
84     return 0;
85 }

最小费用最大流EK

原文地址:https://www.cnblogs.com/hjmmm/p/9261480.html

时间: 2024-11-26 07:50:47

最大流 最小费用流模板的相关文章

最小费用流模板

和最大流模板对比着看:最大流模板(Dinic) 贴上最小费用流模板: const int oo=1e9; const int mm=11111111; const int mn=888888; int node,src,dest,edge; int ver[mm],flow[mm],cost[mm],nex[mm]; int head[mn],dis[mn],p[mn],q[mn],vis[mn]; /**这些变量基本与最大流相同,增加了 cost 表示边的费用, p 记录可行流上节点对应的反向

【bzoj1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. 输出 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 样例输入 5 8 2 1 2 5 8 2 5 9

费用流mcmf模板2.0版

题目地址:HDU 3488 今晚才发现以前的费用流模板居然是错的.......有漏洞....但是居然都AC了那么多题..想想也是..做的费用流也不多,而且都是流量为1的,这个漏洞是不会影响的.因为以前在每次最小费用增广后找到的最小流量是经过的所有路的最小流量,不一定是可以到达汇点的最小流量..但是如果流量都为1的话..那只要边没有全部流过,那肯定最小流量会是1.而如果已经全部流过的话..那也没意义了..已经到达了最大流了.所以说这个漏洞一直都没被发现... 那么应该如何改进呢.那就是跟最短路的方

POJ1459-Power Network-网络流-最大流(EK模板题)

题目链接:http://poj.org/problem?id=1459 好吧,其实就是一道模板题... 但是写的那么长的鸟语...orz...各种揣度题目意思.... 造福一下大家,我把题目数据的意思说一下,就不用看这可恶的英文了... 题目意思:给几个发电站,给几个消耗站,再给几个转发点.发电站只发电,消耗站只消耗电,转发点只是转发电,再给各个传送线的传电能力.问你消耗站能获得的最多电是多少. 首先输入四个数据,分别表示节点数量,发电站的数量,消耗站的数量,以及转发点的数量. 接下来的是m个转

最大流dinci模板

我们知道,增广路EK算法的时间负责度是O(n*m^2),找最短增广路的时间复杂度是O(m*n),所以时间复杂度主要是在找增广路上. 这里介绍另一种Dinci算法,用BFS构造层次图,然后用DFS增广. 模板 #include <cstdio> #include <cstring> #include <iostream> #include <string> #include <algorithm> #include <vector> #

poj2135最小费用最大流经典模板题

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13509   Accepted: 5125 Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of

最小费用最大流基础模板(洛谷3381)

如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向P3381 [模板]最小费用最大流边的个数.源点序号.汇点序号. 接下来M行每行包含四个正整数ui.vi.wi.fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi. 输出格式: 一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用. 输入样例#1:

网络流--最大流dinic模板

标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数.add 函数以及 mf 函数 1 #include<stdio.h> //差不多要加这么些头文件 2 #include<string.h> 3 #include<queue> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 const int maxm=150+5; //点的总数 8

最大流isap模板

isap+bfs初始化+栈优化,点的编号从0开始: 1 const int MAXN = 100010; 2 const int MAXM = 400010; 3 const int INF = 0x3f3f3f3f; 4 struct Edge 5 { 6 int to, next, cap, flow; 7 }edge[MAXM]; 8 int tol; 9 int head[MAXN]; 10 int gap[MAXN], dep[MAXN], cur[MAXN]; 11 void ini