您的位置:首页 > 其它

【bzoj4883】棋盘上的守卫 题解

2017-05-06 23:16 218 查看

题目大意

在一个 n*m 的棋盘上要放置若干个守卫。每行必须恰好放置一个横向守卫,每列必须恰好放置一个纵向守卫。每个位置放置守卫的代价是 w[i][j],且每个位置最多只能放置一个守卫,一个守卫不能同时兼顾行列的防御。请计算控制整个棋盘的最小代价。

n*m<=1e5, w<=1e9

解法1

首先考虑基本的网络流模型:

建两排点,第一排点有 n*m 个,代表每个格子;第二排点有 n+m 个,代表行和列。然后每个格子向其对应的行和列连容量为 1、费用为 w[i][j] 的边,跑最大权匹配。

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

解法2

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

费用流的本质是每次找一条最短的增广路。于是把边按照边权从小到大加入(我是指中间的边,连着源汇的不考虑),假设当前加入的边,权值为 w,左边是 x,它对应的行和列是 i 和 j。

我们维护第二排点的连通性,这里的连通性不是指原图的连通性,而是我另外弄了个并查集,一开始互不连通。如果我把上面的加入操作视作是给 i 和 j 连上一条边,那么这里的每一条边相当于是第一排的一个点,这个连通性就代表第二排点的匹配情况。假如连通性是一棵树,则连通块内必有一点没被匹配;假如连通性是一个图(我们限制他只能是环套树,即一棵树再连一条边),则连通块内所有点都能匹配。(相当于是把边分给点,环套树是可以分完的,而树会空出一个点)

那么对于一个加入操作我们分情况讨论:

1、i 和 j 不连通。那么并查集里面就把它们连起来。假如两个连通块都是树,或者一个树一个图,那当前的 w 就计入答案。

2、i 和 j 连通,连通情况为一棵树。那就把树更新为图,并把 w 计入答案。

3、i 和 j 连通,连通情况为一个图。啥也不干。

这样就用贪心代替费用流了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: