题目描述

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

输入

第一行包含两个正整数n,m(2<=n,m<=100000,n*m<=100000),分别表示棋盘的行数与列数。
接下来n行,每行m个正整数
其中第i行第j列的数w[i][j](1<=w[i][j]<=10^9)表示在第i行第j列放置守卫的代价。

输出

输出一行一个整数,即占领棋盘的最小代价。

样例输入

3 4
1 3 10 8
2 1 9 2
6 7 4 6

样例输出

19


题解

最小环套树森林

首先一眼费用流,然而数据量过大直接卡掉(同时卡掉的还有zkw费用流= =)(跪烂那些用KM算法水过的dalao。。。)

然后经过观察可以发现,如果在行列之间连边,那么答案构成的一定是一个环套树森林。

证明:设行数+列数为n,则构成的图中,点数和边数都为n。如果把每条边选择的方案看作是边的方向的话(a/b中选a看作a->b),那么每个点的出度一定均为1。这样的图一定是环套树森林。因此命题得证。

然后要求的就是无向图的最小环套树森林。

很容易发现环套树森林也是一个拟阵,拟阵最优化问题即可使用贪心算法(Kruscal)求解。

那么本题就和求最小生成树的方法一样了,按边权排序,从小到大加。只需要在原并查集的基础之上,维护每个连通块是否有环,连边时判断即可。

时间复杂度$O(nm\log nm)$

#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;
struct data
{
int x , y , z;
bool operator<(const data &a)const {return z < a.z;}
}a[N];
int f[N] , c[N];
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int n , m , i , j , tx , ty;
long long ans = 0;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= m ; j ++ )
scanf("%d" , &a[(i - 1) * m + j].z) , a[(i - 1) * m + j].x = i , a[(i - 1) * m + j].y = j + n;
sort(a + 1 , a + n * m + 1);
for(i = 1 ; i <= n + m ; i ++ ) f[i] = i;
for(i = 1 ; i <= n * m ; i ++ )
{
tx = find(a[i].x) , ty = find(a[i].y);
if(tx == ty && !c[tx]) c[tx] = 1 , ans += a[i].z;
if(tx != ty && !(c[tx] && c[ty])) f[tx] = ty , c[ty] |= c[tx] , ans += a[i].z;
}
printf("%lld\n" , ans);
return 0;
}

【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林的更多相关文章

  1. [bzoj4883][Lydsy2017年5月月赛]棋盘上的守卫

    来自FallDream的博客,未经允许,请勿转载, 谢谢. 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置 ...

  2. [BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]

    题意 有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价. \ ...

  3. 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

    [BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...

  4. 【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)

    [题解]BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林) 神题 我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不 ...

  5. BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4883 [题目大意] 在一个n*m的棋盘上要放置若干个守卫. 对于n行来说,每行必须恰好 ...

  6. BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小环套树森林&优化定向问题)

    4883: [Lydsy1705月赛]棋盘上的守卫 Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 475  Solved: 259[Submit][St ...

  7. BZOJ4883 棋盘上的守卫(环套树+最小生成树)

    容易想到网络流之类的东西,虽然范围看起来不太可做,不过这提供了一种想法,即将行列分别看做点.那么我们需要找一种连n+m条边的方案,使得可以从每条边中选一个点以覆盖所有点.显然每个点至少要连一条边.于是 ...

  8. bzoj4883 [Lydsy1705月赛]棋盘上的守卫 最小生成基环树森林

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4883 题解 每一行和每一列都必须要被覆盖. 考虑对于每一行和每一列都建立一个点,一行和一列之间 ...

  9. BZOJ4886: [Lydsy1705月赛]叠塔游戏(环套树森林&贪心)

    4886: [Lydsy1705月赛]叠塔游戏 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 198  Solved: 76[Submit][Stat ...

随机推荐

  1. 数据库MySQL基本介绍安装使用及文件导入导出

    1.数据库(data base) 1.1 简述 把文件存储在一台电脑上(服务器),其他电脑用户可以通过账号密码登陆,通过网络去访问这台电脑上的文件,但是由于每个人的数据是不同的,所以你只能通过自己的账 ...

  2. Map the Debris -freecodecamp算法题目

    Map the Debris 1.要求 返回一个数组,其内容是把原数组中对应元素的平均海拔转换成其对应的轨道周期. 原数组中会包含格式化的对象内容,像这样 {name: 'name', avgAlt: ...

  3. 使用ansible安装配置zabbix客户端

    ansible角色简介: 目录名 说明 defaults 默认变量存放目录 handlers 处理程序(当发生改变时需要执行的操作) meta 角色依赖关系处理 tasks 具体执行的任务操作定义 t ...

  4. NuGet管理和还原程序包

    在很多开源的程序下载下来不能使用,一般都是平台X86 和X64没有修改,还一个就是程序缺少资源包文件.用Nuget还原即可: 一般建议先修改好平台,然后用NuGet还原程序包.

  5. sqlite的sql常用语句(笔记)

    1.复制一张表并重命名 比如已经创建好一个表 表名为"28165" 复制这个表. CREATE TABLE [33150] AS SELECT * FROM [28165] 2.根 ...

  6. Shell脚本使用汇总整理

    Shell脚本使用汇总整理 一.Shell脚本常用的头部格式: 头部的作用就是告知linux此脚本的类型: 常用的头部格式如下:(/bin/bash,是bash的路径,如果不知道路径可以通过which ...

  7. python基础回顾笔记

    1.知道了什么是编程语言 2.知道了python.C#.Java都是语言的种类 3.python:有很多种 cpython.pypy.jpython... 4.python的执行方式有两种: 解释器 ...

  8. 搭建MQTT代理服务器

    # 解压tar zxfv mosquitto-1.4.14.tar.gz# 进入目录cd mosquitto-1.4.14# 编译make# 安装sudo make instal 1 启动代理服务在第 ...

  9. macOs 使用Homebrew升级到MySQL 8系列之后,php无法连接解决方法

    当前时间2018-9-28 在使用brew install mysql 默认安装为 MySQL 8,但是使用php连接到数据库之后,出现了这种错误 (Unexpected server respose ...

  10. php-5.6.26源代码 - PHP文件汇编成opcode(require、include的差异)

    文件 php-5.6.26/Zend/zend_language_scanner.c ZEND_API zend_op_array *compile_file(zend_file_handle *fi ...