【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林
题目描述
输入
输出
样例输入
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月月赛]棋盘上的守卫 最小环套树森林的更多相关文章
- [bzoj4883][Lydsy2017年5月月赛]棋盘上的守卫
来自FallDream的博客,未经允许,请勿转载, 谢谢. 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置 ...
- [BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]
题意 有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价. \ ...
- 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法
[BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...
- 【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)
[题解]BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林) 神题 我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不 ...
- BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4883 [题目大意] 在一个n*m的棋盘上要放置若干个守卫. 对于n行来说,每行必须恰好 ...
- BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小环套树森林&优化定向问题)
4883: [Lydsy1705月赛]棋盘上的守卫 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 475 Solved: 259[Submit][St ...
- BZOJ4883 棋盘上的守卫(环套树+最小生成树)
容易想到网络流之类的东西,虽然范围看起来不太可做,不过这提供了一种想法,即将行列分别看做点.那么我们需要找一种连n+m条边的方案,使得可以从每条边中选一个点以覆盖所有点.显然每个点至少要连一条边.于是 ...
- bzoj4883 [Lydsy1705月赛]棋盘上的守卫 最小生成基环树森林
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4883 题解 每一行和每一列都必须要被覆盖. 考虑对于每一行和每一列都建立一个点,一行和一列之间 ...
- BZOJ4886: [Lydsy1705月赛]叠塔游戏(环套树森林&贪心)
4886: [Lydsy1705月赛]叠塔游戏 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 198 Solved: 76[Submit][Stat ...
随机推荐
- python导包学习总结
python初学者,对于导包纠结了不少时间,总结分享,持续前进~ Python导包的两种方法: 1.1 from 包.模块 import 方法名,调用时直接使用方法名() 1.2 from 包. ...
- PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现
PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现 之前记录过一篇文章,不过那只是简单将二维码合成到海报中去,这次还要合成头像,而且是圆形.所需要素材就不一一列举,直接代码吧 1.先获取用 ...
- 完善压缩处理类(支持主流的图像类型(jpg、png、gif)
<?php /* * 图像压缩 */ class Thumb { //成员属性 private $file; //原图文件 private $thumb_path; //压缩文本件保存的地址 / ...
- 学习python第十六天,正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配.采取动态模糊的匹配,最大的应用是爬虫. re 模块使 Python 语言拥有全部的正则表达式功能. compile 函 ...
- 学习python第十三天,函数5 装饰器decorator
定义:装饰器本质是函数,(装饰其他函数)就是为其他函数添加附加功能原则:1.不能修改被装饰的函数的源代码 2.不能修改装饰的函数的调用方式 实现装饰器知识储备1函数即变量2.高阶函数,满足2个条件之一 ...
- PAT (Basic Level) Practice 1040 有几个PAT
个人练习 字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位( ...
- HDU3853 概率DP
LOOPS Homura wants to help her friend Madoka save the world. But because of the plot of the Boss I ...
- 008---Django的模版层
python的模板:HTML代码+模板语法 <!--模版语法之变量--> <h1>Index </h1> <p>{{ name }}</p> ...
- 云心出岫——Splay Tree
(多图预警!!!建议在WI-FI下观看) 之前我们谈论过AVL树,这是一种典型适度平衡的二叉搜索树,成立条件是保持平衡因子在[-1,1]的范围内,这个条件已经是针对理想平衡做出的一个妥协了,但依然显得 ...
- Android 用Chrome浏览器打开url 自定义样式
1.效果预览 1.1.真实效果就是从某一个APP,打开一个url,跳转到谷歌浏览器,返回之后,又回到之前的APP 1.2.说明一下条件 1.手机上必须要安装谷歌浏览器 2.手机上的默认浏览器 ...