LOJ6011「网络流 24 题
来源:互联网 发布:明末农民战争史 知乎 编辑:程序博客网 时间:2024/06/03 22:18
大家都很强, 可与之共勉 。
题意:
然而他要让您输出最小方案和最大方案。
题解:
她都告诉你了流量平衡……直接就是费用流啊。(会不会给人一种硬点的感觉)
虚拟源点
一遍最小费用最大流,一遍最大费用最大流。
其实都可以转化为最小费用最大流,对于最大费用,费用变成相反数,就变成了求最小费用最大流,最后答案是相反数。
# include <bits/stdc++.h>template < class T > inline bool chkmax ( T& d, const T& x ) { return d < x ? ( d = x ), 1 : 0 ; }template < class T > inline bool chkmin ( T& d, const T& x ) { return d > x ? ( d = x ), 1 : 0 ; }# define oo 0x3f3f3f3f# define N 5010# define M 16010class MinCostMaxFlow { private : struct edge { int to, nxt, w, cost ; } g [M << 1] ; int S, T ; int head [N], dis [N], pre [N], ecnt ; inline bool spfa ( int S, int T ) { static std :: bitset < N > inq ; static std :: deque < int > Q ; inq.reset ( ) ; Q.clear ( ) ; memset ( pre, 0, sizeof ( int ) * ( T + 1 ) ) ; memset ( dis, 0x3f, sizeof ( int ) * ( T + 1 ) ) ; Q.push_front ( S ) ; inq [S] = 1 ; dis [S] = 0 ; while ( ! Q.empty ( ) ) { int u = Q.front ( ) ; Q.pop_front ( ) ; inq [u] = 0 ; for ( int i = head [u] ; i ; i = g [i].nxt ) { int& v = g [i].to ; if ( g [i].w && chkmin ( dis [v], dis [u] + g [i].cost ) ) { pre [v] = i ; if ( ! inq [v] ) { ( Q.empty ( ) || dis [v] < dis [Q.front ( )] ) ? Q.push_front ( v ) : Q.push_back ( v ) ; inq [v] = 1 ; } } } } return ( bool ) pre [T] ; } public : MinCostMaxFlow ( ) { ecnt = 1 ; memset ( head, 0, sizeof head ) ; } inline void add_edge ( int u, int v, int w, int cost ) { g [++ ecnt] = ( edge ) { v, head [u], w, cost } ; head [u] = ecnt ; g [++ ecnt] = ( edge ) { u, head [v], 0, -cost } ; head [v] = ecnt ; } std :: pair < int, int > mcmf ( int S, int T ) { this -> S = S, this -> T = T ; int flow = 0, cost = 0, x ; while ( spfa ( S, T ) ) { x = oo ; for ( int i = pre [T] ; i ; i = pre [g [i ^ 1].to] ) chkmin ( x, g [i].w ) ; for ( int i = pre [T] ; i ; i = pre [g [i ^ 1].to] ) { g [i].w -= x, g [i ^ 1].w += x ; cost += x * g [i].cost ; } flow += x ; } return std :: make_pair ( flow, cost ) ; }} Lazer1 ;class MaxCostMaxFlow { private : struct edge { int to, nxt, w, cost ; } g [M << 1] ; int S, T ; int head [N], dis [N], pre [N], ecnt ; inline bool spfa ( int S, int T ) { static std :: bitset < N > inq ; static std :: deque < int > Q ; inq.reset ( ) ; Q.clear ( ) ; memset ( pre, 0, sizeof ( int ) * ( T + 1 ) ) ; memset ( dis, -1, sizeof ( int ) * ( T + 1 ) ) ; Q.push_front ( S ) ; inq [S] = 1 ; dis [S] = 0x3f3f3f3f ; // big enough !!! while ( ! Q.empty ( ) ) { int u = Q.front ( ) ; Q.pop_front ( ) ; inq [u] = 0 ; for ( int i = head [u] ; i ; i = g [i].nxt ) { int& v = g [i].to ; if ( g [i].w && chkmax ( dis [v], dis [u] + g [i].cost ) ) { pre [v] = i ; if ( ! inq [v] ) { ( Q.empty ( ) || dis [v] > dis [Q.front ( )] ) ? Q.push_front ( v ) : Q.push_back ( v ) ; inq [v] = 1 ; } } } } return ( bool ) pre [T] ; } public : MaxCostMaxFlow ( ) { ecnt = 1 ; memset ( head, 0, sizeof head ) ; } inline void clear ( ) { ecnt = 1 ; memset ( head, 0, sizeof head ) ; } inline void add_edge ( int u, int v, int w, int cost ) { g [++ ecnt] = ( edge ) { v, head [u], w, cost } ; head [u] = ecnt ; g [++ ecnt] = ( edge ) { u, head [v], 0, -cost } ; head [v] = ecnt ; } std :: pair < int, int > mcmf ( int S, int T ) { this -> S = S, this -> T = T ; int flow = 0, cost = 0, x ; while ( spfa ( S, T ) ) { x = oo ; for ( int i = pre [T] ; i ; i = pre [g [i ^ 1].to] ) chkmin ( x, g [i].w ) ; for ( int i = pre [T] ; i ; i = pre [g [i ^ 1].to] ) { g [i].w -= x, g [i ^ 1].w += x ; cost += x * g [i].cost ; } flow += x ; } return std :: make_pair ( flow, cost ) ; }} Lazer2 ;# undef N# undef Mint main ( ) { int n, m ; scanf ( "%d%d", & n, & m ) ; const int S = n + m + 1, T = n + m + 2 ; for ( int i = 1 ; i <= n ; ++ i ) { static int x ; scanf ( "%d", & x ) ; Lazer1.add_edge ( S, i, x, 0 ) ; Lazer2.add_edge ( S, i, x, 0 ) ; } for ( int i = 1 ; i <= m ; ++ i ) { static int x ; scanf ( "%d", & x ) ; Lazer1.add_edge ( i + n, T, x, 0 ) ; Lazer2.add_edge ( i + n, T, x, 0 ) ; } for ( int i = 1 ; i <= n ; ++ i ) for ( int j = 1 ; j <= m ; ++ j ) { static int c ; scanf ( "%d", & c ) ; Lazer1.add_edge ( i, j + n, oo, c ) ; Lazer2.add_edge ( i, j + n, oo, c ) ; } printf ( "%d\n%d\n", Lazer1.mcmf ( S, T ).second, Lazer2.mcmf ( S, T ).second ) ; return 0 ;}
阅读全文
0 0
- LOJ6011「网络流 24 题
- loj6011「网络流 24 题」运输问题(费用流)
- 【网络流】网络流24题
- [网络流]: 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 「网络流 24 题」试题库
- 「网络流 24 题」试题库
- LOJ6000 「网络流 24 题
- LOJ6001 「网络流 24 题
- LOJ6002 「网络流 24 题
- LOJ6003 「网络流 24 题
- LOJ6004 「网络流 24 题
- LOJ6005 「网络流 24 题
- LOJ6006「网络流 24 题
- LOJ6007 「网络流 24 题
- 查看apk方法数
- 第一次博客献给了java
- ubuntu 指定开机启动的账户
- 图邻接表实现
- 《看透springMVC源码》笔记之Servlet
- LOJ6011「网络流 24 题
- python简单debug方法
- 个人总结
- RDD、DataFrame和DataSet的区别
- 《深入理解java虚拟机》-目录结构
- cs231n作业1_KNN
- Java array数组
- 用鼠标截取矩形图像并保存(1)
- ACM-12月7日周四周中训练心得