【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)
【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)
神题
我的想法是,每行每列都要有匹配且一个点只能匹配一个,于是就把格点和每行每列建点出来做一个最小生成树,但是不幸的是,这样子无法控制一个点是否选择多次,并且无法控制那些不需要变成守卫的点的情况
然后我看了题解..
一个元素的两种状态可以对应上一条边的方向,现在问题就变成了要选出一些边使得所有点的入度为1。也就是一个外向基环森林,直接类似克鲁斯卡尔做就行了。
这貌似可以抽象成一种模型,也就是有待选点,匹配点,待选点匹配点只能选择且必须选择一个待选点,一个待选点只能选择一个匹配点,同一个点任意选择匹配代价一样。若可以接受\(O(\prod P_i)\)的复杂度其中\(P\)代表一种匹配点的个数,那么就可以这样考虑给边定向构成外向基环森林来做。
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e6+5;
struct E{
int u,v,w;
inline bool operator <(const E&a){return w<a.w;}
};
vector<E> e;
int n,m,cnt;
ll w;
inline void add(const int&fr,const int&to,const int&w){e.push_back({fr,to,w});}
int r[maxn*3],siz[maxn*3],c[maxn*3];
inline int q(const int&x){
int t=x,i=x,temp;
while(t^r[t]) t=r[t];
while(i^r[i]) temp=r[i],r[i]=t,siz[t]+=siz[i],siz[i]=0,c[t]|=c[i],c[i]=0,i=temp;
return t;
}
inline void J(int x,int y){
if(siz[q(x)]>siz[q(y)])swap(x,y);
r[q(x)]=q(y); q(x);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("cpp.in","r",stdin);
freopen("cpp.out","w",stdout);
#endif
n=qr(); m=qr();
cnt=n+m;
for(int t=1;t<=n;++t)
for(int i=1,u;i<=m;++i)
u=qr(),add(t,i+n,u);
for(int t=1;t<=cnt;++t) r[t]=t,siz[t]=1;
sort(e.begin(),e.end());
for(int t=0,ed=e.size();t<ed;++t){
int u=q(e[t].v),v=q(e[t].u);
if(!c[u]||!c[v]){
//printf("%d %d\n",u,v);
if(u==v) c[u]=c[v]=1;
J(u,v),w=w+e[t].w;
}
}
printf("%lld\n",w);
cerr<<"w = "<<w<<endl;
return 0;
}
【题解】BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小生成基环森林)的更多相关文章
- bzoj4883 [Lydsy1705月赛]棋盘上的守卫 最小生成基环树森林
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4883 题解 每一行和每一列都必须要被覆盖. 考虑对于每一行和每一列都建立一个点,一行和一列之间 ...
- [BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]
题意 有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价. \ ...
- BZOJ4883: [Lydsy1705月赛]棋盘上的守卫(最小环套树森林&优化定向问题)
4883: [Lydsy1705月赛]棋盘上的守卫 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 475 Solved: 259[Submit][St ...
- 【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林
题目描述 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个 ...
- [BZOJ4883][Lydsy1705月赛]棋盘上的守卫(Kruskal)
对每行每列分别建一个点,问题转为选n+m条边,并给每条边选一个点覆盖,使每个点都被覆盖.也就是最小生成环套树森林. 用和Kruskal一样的方法,将边从小到大排序,若一条边被选入后连通块仍然是一个环套 ...
- 【BZOJ4883】 [Lydsy1705月赛]棋盘上的守卫(最小生成树,基环树)
传送门 BZOJ Solution 考虑一下如果把行,列当成点,那么显然这个东西就是一个基环树对吧. 直接按照\(Kruscal\)那样子搞就好了. 代码实现 代码戳这里
- BZOJ 4883: [Lydsy1705月赛]棋盘上的守卫 最小生成树 + 建模
Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置 ...
- bzoj 4883 [Lydsy1705月赛]棋盘上的守卫——并查集(思路!)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 把各行和各列看成n+m个点. 如果一下能防守行和列,就是最大匹配了.这是每两个左右部点 ...
- 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法
[BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须 ...
随机推荐
- Java练习 SDUT-2504_多项式求和
多项式求和 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 多项式描述如下: 1 - 1/2 + 1/3 - 1/4 + ...
- Laravel中利用队列发送邮件的方法示例
https://www.jb51.net/article/121647.htm 本文主要给大家介绍了关于Laravel中队列发送邮件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的 ...
- 突然想起一个有趣的问题:FAT32&NTFS?
在大学的时候老师提过一个有意思的问题4G的程序存储在什么格式以上的电脑? 首先普及一下两种格式的区别 FAT32:此硬盘格式不支持4GB以上大文件,使用32位文件分配表. NTFS:微软最新文件格式, ...
- MySQL数据库字符集和整理
MySQL数据库字符集和整理(2009-11-20 22:23:37) mysql数据库 it 其实这个表在MySQL数据库中通过phpMyAdmin就能看到,icech只是把表格整理了一下方便 ...
- php表单加入Token防止重复提交的方法分析
http://www.jb51.net/article/94395.htm 这篇文章主要介绍了php表单加入Token防止重复提交的方法,结合实例形式分析了Token防止重复提交的原理与使用技巧,需要 ...
- uni-app 快速认识
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/阿里/百度/头条/QQ)等多个平台. 即使不跨端,un ...
- Codeforces Round #185 (Div. 1 + Div. 2)
A. Whose sentence is it? 模拟. B. Archer \[pro=\frac{a}{b}+(1-\frac{a}{b})(1-\frac{c}{d})\frac{a}{b}+( ...
- dos taskkill 命令
C:\Users\asn\Desktop>taskkill /? TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter ...
- python3在pycharm中为什么导入random模块不能用? TypeError: 'module' object is not callable
新手学python求大神指导,也用sys导入了random.py的路径,仍然不行. 刚刚排错貌似找到了问题的原因...那是因为我在pycharm中新建的python文件名就是random,所以当前目录 ...
- mysql 第二课 DML操作
DML 数据操纵语句:INSERT UPDATE DELETE SELECT 主要用来对数据库的数据进行一些操作; DCL 数据定义语句:CREATE ALTER DROP 主要是用在定义或改变表的 ...