【bzoj4883】棋盘上的守卫 题解

题目大意

  在一个 $n\cdot m$ 的棋盘上要放置若干个守卫。每行必须恰好放置一个横向守卫,每列必须恰好放置一个纵向守卫。每个位置放置守卫的代价是 $w_{i,j}$,且每个位置最多只能放置一个守卫,一个守卫不能同时兼顾行列的防御。请计算控制整个棋盘的最小代价。
  $n\cdot m \le 10^5,\ \ w \le 10^9$

解法1

  首先考虑基本的网络流模型:
  建两排点,第一排点有 $n \cdot m$ 个,代表每个格子;第二排点有 $n+m$ 个,代表行和列。然后每个格子向其对应的行和列连容量为 $1$、费用为 $w_{i,j}$ 的边,跑最大权匹配。

  据说 zkw 或者 km 什么的大力艹就过了???

解法2

  考虑用贪心来模拟费用流。

  费用流的本质是每次找条最短的增广路。于是把边按照边权从小到大加入(指中间的边),假设当前加入的边,权值为 $w$,它对应的行和列是 $i$ 和 $j$。
  我们维护第二排点的连通性,这里的连通性不是指原图的连通性,而是我另外弄了个并查集,一开始互不连通。如果我把上面的加入操作视作是给 $i$ 和 $j$ 连上一条边,那么这里的每一条边相当于是第一排的一个点,这个连通性就代表第二排点的匹配情况。假如连通性是一棵树,则连通块内必有一点没被匹配;假如连通性是一个图(我们限制他只能是环套树,即一棵树再连一条边),则连通块内所有点都能匹配。(相当于是把边分给点,环套树是可以分完的,而树会空出一个点)

  那么对于一个加入操作我们分情况讨论:
  1、$i$ 和 $j$ 不连通。那么并查集里面就把它们连起来。假如两个连通块都是树,或者一个树一个图,那当前的 $w$ 就计入答案。
  2、$i$ 和 $j$ 连通,连通情况为一棵树。那就把树更新为图,并把 $w$ 计入答案。
  3、$i$ 和 $j$ 连通,连通情况为一个图。啥也不干。

  这样就用贪心代替费用流了。