[BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]
题意
有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价。
\(2\leq n,m\leq 10^5\ ,n*m\leq 10^5\)
分析
将行列看成 \(n+m\) 个点。将每个格点放置守卫看成所在行列连了一条边,然后把每条边定向,如果被指向表示当前格点对当前 行/列 进行了保护。
这样就会有 \(n+m\) 个点,\(n+m\) 条有向边,同时每条边最多有 1 的入度。形成了基环树森林。
最小基环树森林可以通过 \(Kruskal\) 贪心求解,证明仍然可以考虑反证法。
总时间复杂度为 \(O(n)\) 。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5 + 7;
int n,m,edc;
int par[N],c[N];
struct edge{
	int last,to,dis;
	edge(){}edge(int last,int to,int dis):last(last),to(to),dis(dis){}
	bool operator <(const edge &rhs)const{
	  return dis<rhs.dis;
	}
}e[N*2];
int getpar(int a){return par[a]==a?a:par[a]=getpar(par[a]);}
LL Kruskal(){
    sort(e+1,e+1+edc);int cnt=0;LL res=0;
    for(int i=0;i<N;i++) par[i]=i;
	for(int i=1;i<=edc;i++){
		int x=getpar(e[i].last),y=getpar(e[i].to);0
		if(x==y&&!c[x]) c[x]=1,cnt++,res+=e[i].dis;
		if(x!=y&&!(c[x]&&c[y])) par[x]=y,c[y]|=c[x],cnt++,res+=e[i].dis;
		if(cnt==n+m) return res;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	for(int j=1,x;j<=m;j++){
		scanf("%d",&x);
		e[++edc]=edge(i,j+n,x);
	}
	printf("%lld\n",Kruskal());
	return 0;
}
												
											[BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]的更多相关文章
- 【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)
		
[题解]BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林) 神题 我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不 ...
 - bzoj4883 [Lydsy1705月赛]棋盘上的守卫   最小生成基环树森林
		
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4883 题解 每一行和每一列都必须要被覆盖. 考虑对于每一行和每一列都建立一个点,一行和一列之间 ...
 - 【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫  最小环套树森林
		
题目描述 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个 ...
 - BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小环套树森林&优化定向问题)
		
4883: [Lydsy1705月赛]棋盘上的守卫 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 475 Solved: 259[Submit][St ...
 - [BZOJ4883][Lydsy1705月赛]棋盘上的守卫(Kruskal)
		
对每行每列分别建一个点,问题转为选n+m条边,并给每条边选一个点覆盖,使每个点都被覆盖.也就是最小生成环套树森林. 用和Kruskal一样的方法,将边从小到大排序,若一条边被选入后连通块仍然是一个环套 ...
 - BZOJ 4883: [Lydsy1705月赛]棋盘上的守卫 最小生成树 + 建模
		
Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置 ...
 - [CF1027F]Session in BSU[最小基环树森林]
		
题意 有 \(n\) 门课程,每门课程可以选择在 \(a_i\) 或者 \(b_i\) 天参加考试,每天最多考一门,问最早什么时候考完所有课程. \(n\leq 10^6\). 分析 类似 [BZOJ ...
 - 【BZOJ4883】 [Lydsy1705月赛]棋盘上的守卫(最小生成树,基环树)
		
传送门 BZOJ Solution 考虑一下如果把行,列当成点,那么显然这个东西就是一个基环树对吧. 直接按照\(Kruscal\)那样子搞就好了. 代码实现 代码戳这里
 - BZOJ4886: [Lydsy1705月赛]叠塔游戏(环套树森林&贪心)
		
4886: [Lydsy1705月赛]叠塔游戏 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 198 Solved: 76[Submit][Stat ...
 
随机推荐
- Java——并发编程
			
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...
 - Java 系统学习梳理_【All】
			
Java基础 1. Java学习---JDK的安装和配置 2. Java学习---Java代码编写规范 2. Java学习---HashMap和HashSet的内部工作机制 3. Java学习---J ...
 - 【Pygame】  简易五子棋
			
import pygame import sys import time import random pygame.init() screen_size = (800,560) WIDTH = 720 ...
 - mysql8.0 安装
			
之前一直使用的是zabbix3.4和mariadb5.5;感觉良好!!!但是...因其他原因需要重新部署 这次规划使用zabbix4.0和mysql8.0结合使用:嗯~~应该不会错吧!!! zabbi ...
 - jQuery 3D圆盘旋转焦点图 支持鼠标滚轮
			
之前我们分享过很多炫酷实用的jQuery焦点图插件了,今天介绍的这款jQuery焦点图非常特别,所有图片围成一个圆圈,组成一个立体视觉的圆盘,并且可以旋转选择圆盘中的图片.另外,这款jQuery 3D ...
 - 检查oracle用户默认密码的账户
			
1. 检查使用默认用户密码的账号 --11g 通过数据字典SYS.DEFAULT_PWD$或视图DBA_USERS_WITH_DEFPWD select u.username, u.account_s ...
 - Hive学习之路 (八)Hive中文乱码
			
Hive注释中文乱码 创建表的时候,comment说明字段包含中文,表成功创建成功之后,中文说明显示乱码 create external table movie( userID int comment ...
 - Day1 Mybatis初识(一)
			
框架 将重复的,繁琐的代码实现封装,让程序员将更多的精力放在业务的理解和分析上. 框架的作用 提高开发效率 隐藏细节 三大框架SSH --> SSM 1) 表述层: 用户 ...
 - java final使用
			
一:final 1:有时候 我们需要一些类,不要被继承.即阻止定义子类.不允许扩展的类叫做final类,如果一个类在定义的时候,用final定义的时候,表示这个类是final类.无法定义子类. 语法 ...
 - 使用Charles进行移动APP抓包分析
			
一.简介 Charles是目前最强大最流行的http抓包调试工具,Mac.Unix.Windows各个平台都支持.特别是做APP开发,调试与服务端的通信,Charles是必备工具. 目前Charles ...