【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 ...
 
随机推荐
- 插入数据返回自增id及插入更新二合一
			
原文https://blog.csdn.net/dumzp13/article/details/50984413 JDBC: con.setAutoCommit(false); String sql ...
 - java通过FreeMarker模板生成Excel文件之.ftl模板制作
			
关于怎么通过freemarker模板生成excel的文章很多,关键点在于怎么制作模板文件.ftl 网上的办法是: (1)把Excel模板的格式调好,另存为xml文件 (2)新建一个.ftl文件,把xm ...
 - js中document的用法小结
			
document常用属性: document.title//设置文档标题,与HTNL中的title标签等价 document.bgColor//设置页面背景颜色 document.fgColor//设 ...
 - css设置内容超出后显示省略号
			
1.使用overflow: hidden把超出的内容进行隐藏: 2.然后使用white-space: nowrap设置内容不换行: 3.最后使用text-overflow: ellipsis设置超出内 ...
 - C语言字符篇(一)字符串转换函数
			
#include <stdlib.h> double atof(const char *nptr); 将字符串转换成双精度浮点数 int atoi(const char *npt ...
 - sql查询平均下单时间
			
SQL查询订单平均审核时长 今天在写一个sql,需求是算一个订单在执行状态中的各个节点的时长 比如在订单中,状态0为开始接单,状态3为已经审核,那么现在需要计算每个客服的平均审核时长 像图中所示:这个 ...
 - POJ:3685-Matrix
			
Matrix Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 7879 Accepted: 2374 Description Gi ...
 - POJ:2429-GCD & LCM Inverse(素数判断神题)(Millar-Rabin素性判断和Pollard-rho因子分解)
			
原题链接:http://poj.org/problem?id=2429 GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K To ...
 - 3,MongoDB之数据类型
			
一.MongoDB 之数据类型 首先我们要先了解一下MongoDB中有什么样的数据类型: Object ID :Documents 自生成的 _id String: 字符串,必须是utf-8 Boo ...
 - 以最省内存的方式把大图片加载到内存及获取Exif信息和获取屏幕高度和宽度的新方法
			
我们在加载图片时经常会遇到内存溢出的问题,图片太大,我们加载图片时,一般都是用的如下一般方法(加载本地图片): /** * 不作处理,去加载图片的方法,碰到比较大的图片会内存溢出 */ private ...