BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)
2024-09-29 12:12:16
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4883
【题目大意】
在一个n*m的棋盘上要放置若干个守卫。
对于n行来说,每行必须恰好放置一个横向守卫;同理对于m列来说,
每列必须恰好放置一个纵向守卫。每个位置放置守卫的代价是不一样的,
且每个位置最多只能放置一个守卫,一个守卫不能同时兼顾行列的防御。
请计算控制整个棋盘的最小代价。
【题解】
我们将每行和每列看成一个点,用每个格子上的点的权值作为边,
这就构成了一个n+m个点的图。
我们发现对于n个点的集合,为了满足题目中的要求,就至少要包含n条边。
所以题目就转化成求图中的最小生成环套树森林。
【代码】
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=200010;
LL ans;
int x,n,m,f[N],v[N];
struct E{int u,v,c;E(){}E(int u,int v,int c):u(u),v(v),c(c){};}e[N];
bool cmp(E x,E y){return x.c<y.c;}
int sf(int x){return x==f[x]?x:f[x]=sf(f[x]);}
int main(){
while(~scanf("%d%d",&n,&m)){
int cnt=ans=0;
for(int i=1;i<=n+m;i++)f[i]=i,v[i]=0;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
scanf("%d",&x);
e[++cnt]=E(i,j+n,x);
}sort(e+1,e+cnt+1,cmp);
for(int i=1;i<=cnt;i++){
int fx=sf(f[e[i].u]),fy=sf(f[e[i].v]);
if(v[fx]&&v[fy])continue;
if(fx!=fy)v[fy]|=v[fx],f[fx]=fy;else v[fx]=1;
ans+=e[i].c;
}printf("%lld\n",ans);
}return 0;
}
最新文章
- Oracle中生成随机数的函数(转载)
- 【云计算】docker前世今生
- apt-get命令详解
- [电子书] 《Android编程入门很简单》
- JAVA排序--[选择排序]
- iOS进阶学习-数据处理之文件读写
- 254. Factor Combinations
- css中bug记录
- 随机法解决TSP问题
- IDL 的读写
- jq交叉淡入淡出轮播图
- 软件工程第三次作业-结对作业NO.1
- zipline-benchmarks.py文件改写
- 【Chrome插件】去掉因使用jsonView插件的弹出窗口";请停用以开发者模式运行的扩展程序";
- XAML: 在 MVVM 模式中,关于绑定的几处技巧
- Trident的过滤操作
- 十六、springcloud(二)Eureka集群
- python全局解释器锁(GIL)
- spring冲刺第三天
- Javascript的执行过程详细研究
热门文章
- linux 3389连接工具Rdesktop
- vue中的图片加载与显示默认图片
- Vue组件-使用插槽分发内容
- Linux 入门记录:二、Linux 文件系统基本结构
- sicily 1059. Exocenter of a Trian
- 生命周期(vue的钩子函数)
- django开发项目实例3--用session是实现简单的登陆、验证登陆和注销功能
- linux命令(15):mount/umount命令
- LeetCode解题报告—— Word Search &; Subsets II &; Decode Ways
- QT中ui更改后不能更新的解决方法