欢迎光临 ~|

Laijinyi

园龄:1年7个月粉丝:2关注:2

网络流 口胡

我是口胡大王

允许负流量有上下界的源-汇最大流(已实现)

  • TS 上界 inf,下界 inf 的边
  • 无源汇可行流 有源汇最大流,注意到此时已经没有负容量了;找到此时 TS 边的流量
  • s,t 点、TSinf 边,再跑最大流

无负环的最小费用源-汇最大流(已实现)

  • 直接 Simplex

有上下界、负权环和源汇的最小费用可行流、最大流和最小流(已实现)

  • 先连 TS 上界 inf,下界 inf,费用 0 的边
  • 无源汇可行流 有源汇最大流,判断是否可行,找到此时 TS 边的流量
  • 把这张图复制三遍,跑三遍 Simplex

全非负权的最小权稀疏二分图匹配(已实现)

  • 费用流,秒了!

最小权稠密二分图匹配(已实现)

  • 费用流,秒了!

最大最小欧拉回路(已实现)

  • 二分答案,问题变成:给无向边定向,问能不能构成欧拉回路
  • 有向图为欧拉图的充要条件:每个点出度等于度数的一半
  • 若边 (u,v) 有向,他给 u 提供 1 的出度,若无向,给 uv 提供 1 的出度
  • i 建点 ei,点 u 建点 pusei 容量为 1pit 容量为 deg(i)2,若 i(u,v) 有向,则 eipu 连容量为 1 的边,否则向 pu,pv 连容量为 1 的边
  • 跑最大流,看是否满流、再看哪些 eipj 流过了即可定向,最后 DFS 输出方案即可。

= P3511

环形铁路

数学做法

  • 总货物数一定,故每个库最后拥有的货物数一定,故每个库要转出或转入的货物数一定
  • 因为每个库只能和两个库交易,故确定和一个库的交易后即可确定与另一个库的交易
  • 推广发现,若确定其中一组相邻的交易,就能确定其余所有交易,答案就是个一元函数
  • 1n 交易了 x,每个库所需转出量为 ai,则 21 交易 xa132 交易 (xa1)a243 交易 ((xa1)a2)a3……
  • biai 前缀和,Ans=minx{|xb0|+|xb1|++|xbn1|},搞出中位数代入计算即可
  • O(n)

费用流做法

  • 设货物数量序列为 am=a¯,下标从 0 开始,c 为容量、p 为费用
  • 建点 s,t,每个仓库 i 建点 pi
  • i[1..n]pip(i1)modnpip(i+1)modnc=+p=1
  • i[1..n]ai>mspic=aimp=0
  • i[1..n]ai<mpitc=maip=0
  • 跑最小费用最大流,最小费用即为答案

= P4016

卖猪

  • 建点 s,t,每个客人 i 建点 qi
  • i[1..n],vKi
    • iv 的第一个客人,sqic=pv
    • 否则,设上一个客人为 jqjqic=+
  • i[1..n]qitc=bi
  • 跑最大流,最大总流量即为答案

= POJ 1149

志愿者招募

  • l 为流量下界,u 为流量上界,p 为费用
  • i 天建点 Fi,Gi
  • i[1..n]FiGil=Aiu=+p=0
  • i[1..n1]GiFi+1l=0u=+p=0
  • j[1..m]GTjFSjl=0u=+p=Cj
  • 跑最小费用可行流,最小费用即为答案

= P3980

餐巾问题

  • l 为流量下界,u 为流量上界,p 为费用
  • 建点 s,t,第 i 天建点 Fi,Gi
  • i[1..n]
    • FiGil=riu=+p=0
    • sFil=0u=+p=p1
    • Gitl=0u=+p=0
  • i[1..n1]FiFi+1l=0r=+p=0
  • i[1..nt2]GiFi+t2l=0r=+p=p2
  • i[1..nt3]GiFi+t3l=0r=+p=p3
  • 跑最小费用可行流,最小费用即为答案

= P1251

星际转移问题

  • pii 船的停靠站周期序列(pi 内下标从 0 开始),ki=|pi|c 为容量
  • 无解条件:
    • i[1..m],j[0..ki2],并查集中合并 pi,j,pi,j+1 连通块
    • 0,1 不连通,则无解
  • 从小到大枚举答案 x,每次在上一张图的残量网络上继续加边继续跑
  • 建点 s,t,对于每个站点 i[1..n]、每个时间 t[0..x],建点 q(i,t)
  • x=0 时:
    • sq(0,0)c=k
    • q(1,0)tc=+
  • 否则,新加边:
    • j[1..m]q(pj,(x1)modkj,x1)q(pj,xmodkj,x)c=hj
    • i[0..n]q(i,x1)q(i,x)c=+
    • q(1,x)q(1,x1)c=+
  • 若满流则 x 满足条件,退出
  • 答案上界:
    • 研究一条可行的流,他的流量至少为 1
    • 首先他不会重复经过一个点,因为你总可以将其替换成一直在该点停留
    • 其次在一个点停留的时间至多为 n+2,因为假如存在一个经过该点的船,他最多隔 n+2 的时间就会访问到该点
    • 故答案上界为 k(n+2)2=11250
  • 因为答案 11250,故点数、边数不会爆炸
  • 该方法比直接二分快

= P2754

管道清洁

  • l 为流量下界,r 为流量上界,p 为费用
  • 建边:
    • 对于一号边 (u,v),建边 uvl=1r=1p=1
    • 对于二号边 (u,v),建边 uvl=1r=+p=1
    • 对于三号边 (u,v),建边 uvl=0r=1p=1
    • 对于四号边 (u,v),建边 uvl=0r=+p=1
  • 1 号点拆为 s,t1 的所有出边由 s 连出、所有入边由 t 连入
  • 跑源-汇最小费用可行流,可以判有/无解,若有解则最小费用为答案

宝石问题

  • 设机器人起点集合为 B、终点集合为 Ec 为容量,p 为费用
  • 建点 s,t,每个格子 (i,j) 拆为两个点 p1(i,j),p2(i,j)
  • i[1..r],j[1..c]
    • p1(i,j)p2(i,j)c=1p=vi,j
    • p1(i,j)p2(i,j)c=+p=0
  • i[1..r],j[1..c1]p2(i,j)p1(i,j+1)c=+p=0
  • i[1..r1],j[1..c]p2(i,j)p1(i+1,j)c=+p=0
  • (i,j)Bsp1(i,j)c=1p=0
  • (i,j)Ep2(i,j)tc=1p=0
  • 跑源-汇最小费用最大流,最小费用的相反数即为答案

双向路径问题

暴力

  • c 为容量,p 为费用
  • 建点 S,T,原图每个点 u 拆为 pu,qu
  • u[1..n]puquc=1p=1
  • Sqsc=2p=0
  • ptTc=2p=0
  • 对于原图边 (u,v),建边 qupvc=+p=0
  • 跑最大费用最大流,若满流则有解,答案为最大费用
  • O(nm),不能通过

优化 1

  • 用单纯形网络流碾过去
  • 理论复杂度为指数级

优化 2

  • 考虑原始对偶的过程,发现第一次 SPFA 可以替换成 DAG 上的 DP
  • O(mlogn)

同余最大流

  • f 为流量,L 为流量下界,U 为流量上界
  • 首先,eE,r(e)r(e)modQ
  • 原题相当于,你要对每条边 (u,v,L,U,r) 定一个 k,令其流量为 r+kQ,需要满足:
    • 流量平衡条件
    • 流量上下界条件
    • 有解情况下,最大化 (s,v,f)f
  • 首先,若 u[1..n],(v,u,L,U,r)Er(u,v,L,U,r)Er(modQ),则无解
  • cu=(v,u,L,U,r)Er(u,v,L,U,r)ErQ
  • 考虑建出新图,新图中每条边的流量对应原图中该边的 k
  • 建点 S,T,对于原图中每个点 u 建点 du
  • 对原图每条边 (u,v,L,U,r) 算出满足 r+kQ[L..U]k 的取值范围 [p..q],若不存在 k 使条件满足,则无解;否则在新图中建边 dudvL=pU=q
  • 对于每个点 u[1..n],若 cu>0,建边 SduL=0U=cu;若 cu<0,建边 duTL=0U=cu
  • 先以 S 为源点、T 为汇点做源-汇最大流,求出一组可行流;然后删去 S,T 点,在可行流的基础上做以 s 为源点、t 为汇点的源-汇最大流

最小割模型

最小割问题

最大流 = 最小割

最大权闭合子图

闭合子图:对于有向图,我们选一些点,若 u 被选,则任意 u 连出的点 v 都被选。

最大权闭合子图:每个点有点权,要求闭合子图点权和最大

  • 设原图 =(V,E),点 u 权值为 au,边权为 c
  • 建点 s,t,每个点 u 建点 pu
  • uV,au>0,建边 spuc=|au|
  • uV,au<0,建边 putc=|au|
  • (u,v)E,建边 pupvc=+
  • 答案 = 正点权和 最小割

正确性:

  • 先把所有正点权给选了
  • S 集合表示选的点集,T 集合表示不选的点集
  • 第 3 类边表示,若 u 选了,v 也必须选
  • 第 1 类边表示,若正权点 u 不被选,代价增加 |au|
  • 第 2 类边表示,若负权点 u 被选,代价增加 |au|

最小点割集

一张图,给出 s,t,每个点有正点权,求一个不包含 s,t 的权值和最小的点集,使得删掉点集中所有点后 s 无法到达 t

  • 把点拆成入点和出点,入点向出点连边,边权为该点点权
  • 原图边从出点连向入点,边权为 +
  • 最小割即为答案

最小冲突投票

例题:BZOJ 1934

n 个人,m 对好友关系,每个人可以给 A 或 B 投票,每个人都有自己的意愿(倾向于 A 还是 B)。

定义一次投票的冲突数为“好友之间投票冲突的总数”加上“和自己本来意愿发生冲突的人数”,问如何投票,冲突数最小。

  • S 表示投 A 的集合,T 表示投 B 的集合,c 为边权
  • 建点 s,t
  • i[1..n]
    • i 想投 A,sic=1
    • i 想投 B,itc=1
  • 对于一对好友关系 (u,v),连边 uvc=1
  • 最小割即为答案

组合收益

每个物品 i 有收益 ai(可以为负),若 xj,yj 同时被选会额外获得收益 vj,问最大收益。

  • 先把所有正收益全选了
  • S 集合表示选的物品,T 集合表示没选的物品
  • 每个组合 j 建点 pj
  • ai>0sic=|ai|
  • ai<0itc=|ai|
  • pjxjpjyjc=+
  • vj>0spjc=|vj|
  • vj<0pjtc=|vj|
  • 答案等于正收益之和减去最小割

黑白染色

把所有点分为两个集合,i 在两个集合分别获得的收益为 ai,bi,如果 xj,yj 所在集合不同会获得一个收益,否则会付出一个代价。

  • 先把所有点黑白染色,分成两类点,需要满足同一类点之间没有限制条件
  • S 为在第一个集合,T 为在第二个集合
  • 对于第一类收益:
  • 对于黑色点,正常向 s,t 连边
  • 对于白色点,反转源汇,即把 s 看成 t、把 t 看成 s,然后连边
  • 对于第二类收益:
  • 问题变成了若所在集合相同则获得收益、所在集合不同则付出代价,正常连边即可
  • 答案为所有收益之和减去最小割

最小割树

无向图最小割性质:设 s,t 为任意两点,设 st 的最小割为 c,且把点分成了集合 ST,则 uS,vTuv 的最小割 c

最小割树:点集中任取 s,t,在原图中跑出最小割 c 把点集分成 S,T,按 S,T 划分当前点集,向两边递归,再用一个权值为 c 的点连接两边的点集,像 Kruskal 重构树一样

u,v 最小割等于 u,v 路径上的点权最小值.

证明考虑最小割的最小性和唯一性。

例题

最大密度子图

定义无向图 G=(V,E) 的密度为 |E||V|,问子图的最大密度及方案。

  • 二分答案 g,问题变成判定:有没有子图满足 |E||V|g,即求出 max{|E|g|V|}
  • 整理条件:
    • 选择子图时,如果选了某条边,那么他的两个端点也必须被选
    • 选了一条边,产生贡献 1
    • 选了一个点,产生贡献 g
  • 得出方法:
    • 把原图的点、边一律视为点
    • 从边变成的点向其两个端点连一条有向边
    • 将边的点权设为 1,点的点权设为 g
    • 在新图中求出最大权闭合子图,答案就是我们要求的 max{|E|g|V|}
  • 对于输出方案,把选了的点和边输出即可

最小权点覆盖

对于二分图,选一些点去覆盖他们相邻的边,使得所有边被覆盖,问选出的点权和最小是多少。

  • 建点 s,t
  • 对于所有左部点 usu,权值为 u 的点权
  • 对于所有右部点 vvt,权值为 v 的点权
  • 对于原图边 (u,v)uv,权值为 +
  • 求出最小割即为答案

这里割一条边就相当于选一个点

最大权独立集

等于总权值 最小权点覆盖,之前证过。

习题

植物大战僵尸

最大权闭合子图。注意环。

奶牛的电信

最小点割集。

最小边异或和

  • 首先按位考虑,每个点要么是 1,要么是 0,要么还没定,目标是最小化异或和
  • S 为 0 集合,T 为 1 集合
  • 对于原图边 (u,v)
    • 若两个点权已经给定,直接计入答案
    • 若给定一个点权,假设为 v
    • av=0,连边 su,权值为 1
    • av=1,连边 ut,权值为 1
    • 若两个点权都待定,连边 uv,权值为 1
  • 最小割即为答案

逃出包围圈

最小点割集。

建图就是把上平面、下平面,以及每个圆看成一个点,把相交 / 相切关系看成一条边

猫狗大战

  • S 为获奖的猫 / 不获奖的狗,T 为不获奖的猫 / 获奖的狗
  • 建点 s,t,猫 i 建点 ci,狗 j 建点 dj
  • 对于所有猫 u,设其支持人数为 rscuc=r
  • 对于所有狗 v,设其支持人数为 rdvtc=r
  • 对于所有猫 u、所有狗 v,设支持猫 u、不支持狗 v 的猫粉数量,与不支持猫 u、支持狗 v 的狗粉数量之和为 rcudvc=r
  • 总人数减去最小割即为答案

综合习题

无限之环

黑白染色 + 大力讨论 + 费用流

Code
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define reo(i, j, k) for (int i = (j); i >= (k); --i)
typedef long long ll;
const int N = 2001, dir[4][2] = {
{-1, 0}, {0, 1}, {1, 0}, {0, -1}
};
const int INF = 0x3f3f3f3f;
vector<vector<array<int, 5>>> p;
vector<vector<int>> a, b;
int n, m, s, t;
struct Edge {
int u, v, n, w, c;
} e[50001];
int pnode, pedge = 1, h[10001], cur[10001];
int SumF;
void add_edge(int u, int v, int w, int c) {
e[++pedge] = {u, v, h[u], w, c}, h[u] = cur[u] = pedge;
}
void Add_edge(int u, int v, int w, int c, int d = 0) {
if (d) swap(u, v);
add_edge(u, v, w, c), add_edge(v, u, 0, -c);
}
void build_graph() {
p.assign(n, vector<array<int, 5>>(m));
b.assign(n, vector<int>(m));
rep(i, 0, n - 1)
rep(j, 0, m - 1)
rep(k, 0, 4)
p[i][j][k] = ++pnode;
s = ++pnode, t = ++pnode;
rep(i, 0, n - 1)
rep(j, 0, m - 1)
b[i][j] = (i + j) % 2;
rep(i, 0, n - 1) {
rep(j, 0, m - 1) {
if (!b[i][j]) {
rep(k, 0, 3) {
int x = i + dir[k][0], y = j + dir[k][1];
if (0 <= x && x <= n - 1 && 0 <= y && y <= m - 1) {
Add_edge(p[i][j][k + 1], p[x][y][(k ^ 2) + 1], 1, 0);
Add_edge(p[x][y][(k ^ 2) + 1], p[i][j][k + 1], 1, 0);
}
}
}
}
}
rep(i, 0, n - 1) {
rep(j, 0, m - 1) {
int d = __builtin_popcount(a[i][j]);
if (b[i][j] == 0) {
Add_edge(s, p[i][j][0], d, 0);
SumF += d;
} else {
Add_edge(p[i][j][0], t, d, 0);
}
}
}
rep(i, 0, n - 1) {
rep(j, 0, m - 1) {
if (a[i][j] == 0) {
;
}
if (a[i][j] == 1) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][1], p[i][j][2], 1, 1, b[i][j]);
Add_edge(p[i][j][1], p[i][j][4], 1, 1, b[i][j]);
Add_edge(p[i][j][1], p[i][j][3], 1, 2, b[i][j]);
}
if (a[i][j] == 2) {
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][2], p[i][j][1], 1, 1, b[i][j]);
Add_edge(p[i][j][2], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][2], p[i][j][4], 1, 2, b[i][j]);
}
if (a[i][j] == 3) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][1], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][2], p[i][j][4], 1, 1, b[i][j]);
}
if (a[i][j] == 4) {
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][3], p[i][j][4], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][2], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][1], 1, 2, b[i][j]);
}
if (a[i][j] == 5) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
}
if (a[i][j] == 6) {
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][2], p[i][j][4], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][1], 1, 1, b[i][j]);
}
if (a[i][j] == 7) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][1], p[i][j][4], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][4], 1, 1, b[i][j]);
Add_edge(p[i][j][2], p[i][j][4], 1, 2, b[i][j]);
}
if (a[i][j] == 8) {
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][4], p[i][j][1], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][2], 1, 2, b[i][j]);
}
if (a[i][j] == 9) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][1], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][2], 1, 1, b[i][j]);
}
if (a[i][j] == 10) {
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
}
if (a[i][j] == 11) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][2], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][3], 1, 1, b[i][j]);
Add_edge(p[i][j][1], p[i][j][3], 1, 2, b[i][j]);
}
if (a[i][j] == 12) {
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][3], p[i][j][1], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][2], 1, 1, b[i][j]);
}
if (a[i][j] == 13) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][1], p[i][j][2], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][2], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][2], 1, 2, b[i][j]);
}
if (a[i][j] == 14) {
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
Add_edge(p[i][j][2], p[i][j][1], 1, 1, b[i][j]);
Add_edge(p[i][j][4], p[i][j][1], 1, 1, b[i][j]);
Add_edge(p[i][j][3], p[i][j][1], 1, 2, b[i][j]);
}
if (a[i][j] == 15) {
Add_edge(p[i][j][0], p[i][j][1], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][2], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][3], 1, 0, b[i][j]);
Add_edge(p[i][j][0], p[i][j][4], 1, 0, b[i][j]);
}
}
}
}
int nw, fa[10001], fe[10001], cir[10001], tag[10001];
int sum[10001];
void DFS(int u, int f, int c) {
fa[u] = e[f].u, fe[u] = f, tag[u] = c;
for (int i = h[u]; i; i = e[i].n)
if (e[i].w && tag[e[i].v] != c) DFS(e[i].v, i, c);
}
int Sum(int u) {
if (tag[u] == nw) return sum[u];
return tag[u] = nw, sum[u] = Sum(fa[u]) + e[fe[u]].c;
}
int Push(int o) {
int cnt = 0, del = 0, P = 2;
int C = 0, F = e[o].w;
++nw;
int q = e[o].u, lca = e[o].v;
while (q) tag[q] = nw, q = fa[q];
while (tag[lca] != nw) tag[lca] = nw, lca = fa[lca];
for (int u = e[o].u; u != lca; u = fa[u]) {
cir[++cnt] = fe[u];
if (e[fe[u]].w < F) F = e[fe[u]].w, del = u, P = 0;
}
for (int u = e[o].v; u != lca; u = fa[u]) {
cir[++cnt] = fe[u] ^ 1;
if (e[fe[u] ^ 1].w < F) F = e[fe[u] ^ 1].w, del = u, P = 1;
}
cir[++cnt] = o;
rep(i, 1, cnt) C += F * e[cir[i]].c, e[cir[i]].w -= F, e[cir[i] ^ 1].w += F;
if (P == 2) return C;
int u = e[o].u, v = e[o].v;
if (P) swap(u, v);
int lste = o ^ P, lstu = v, tmp;
while (lstu != del) {
swap(fe[u], lste ^= 1), --tag[u];
tmp = fa[u], fa[u] = lstu, lstu = u, u = tmp;
}
return C;
}
void Simplex() {
Add_edge(t, s, INF, -INF);
DFS(t, 0, ++nw), tag[t] = ++nw, fa[t] = 0;
int F = 0, C = 0, ok = 1;
while (ok) {
ok = 0;
rep(i, 2, pedge)
if (e[i].w && e[i].c + Sum(e[i].u) - Sum(e[i].v) < 0)
C += Push(i), ok = 1;
}
F = e[pedge].w;
C += e[pedge].w * INF;
if (F == SumF) {
cout << C << '\n';
} else {
cout << "-1\n";
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m;
a.assign(n, vector<int>(m));
rep(i, 0, n - 1) {
rep(j, 0, m - 1) {
cin >> a[i][j];
}
}
build_graph();
Simplex();
return 0;
}

本文作者:Laijinyi

本文链接:https://www.cnblogs.com/laijinyi/p/18544610

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Laijinyi  阅读(5)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起