题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883

首先,注意到每个点可横可竖,但花费一样;

所以考虑行列的交集,那么这个条件可以转化为行点和列点之间的边,边权就是花费;

如果行和列都按原图交点连了边,那么问题就转化成在有向图中,每个点(原图的行/列)都有且仅有1入度;

这个性质让我们联想到基环树,所以只需要构造一个基环树森林即可;

又要边权和最小,仿照 Kruskal,从小到大加边,对于连通块,看看是否已经有环即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=2e5+;
int n,m,ct,fa[xn];
ll ans;
bool v[xn];
struct N{int u,v,w;}ed[xn<<];
bool cmp(N x,N y){return x.w<y.w;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
int main()
{
n=rd(); m=rd();
for(int i=;i<=n;i++)
for(int j=,z;j<=m;j++)
{
z=rd();
ed[++ct].u=i; ed[ct].v=j+n; ed[ct].w=z;
}
for(int i=;i<=n+m;i++)fa[i]=i;
sort(ed+,ed+ct+,cmp);
for(int i=;i<=ct;i++)
{
int x=find(ed[i].u),y=find(ed[i].v),w=ed[i].w;
if(x==y)
{
if(v[x])continue;
else ans+=w,v[x]=;
}
else
{
if(v[x]&&v[y])continue;
else if(v[x]||v[y])ans+=w,fa[x]=y,v[y]=;
else ans+=w,fa[x]=y;
}
}
printf("%lld\n",ans);
return ;
}

bzoj 4883 棋盘上的守卫 —— 基环树转化的更多相关文章

  1. BZOJ 4883 棋盘上的守卫 解题报告

    BZOJ4883 棋盘上的守卫 考虑费用流,但是数据范围太大 考虑 \(i\) 行 \(j\) 列如果被选择,那么要么给 \(i\) 行,要么给 \(j\) 列 把选择 \(i\) 行 \(j\) 列 ...

  2. BZOJ4883 棋盘上的守卫 基环树、Kruskal

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 题意:给出一个$N \times M$的棋盘,每个格子有权值.你需要每一行选中一 ...

  3. BZOJ 1040: [ZJOI2008]骑士(基环树dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题意: 思路: 这是基环树,因为每个人只会有一个厌恶的人,所以每个节点只会有一个父亲节点,但是 ...

  4. BZOJ 1791: [IOI2008]Island 岛屿 - 基环树

    传送门 题解 题意 = 找出无向基环树森林的每颗基环树的直径. 我们首先需要找到每颗基环树的环, 但是因为是无向图,用tarjan找环, 加个手工栈, 我也是看了dalao的博客才知道tarjan找无 ...

  5. bzoj 1040: [ZJOI2008]骑士【基环树+树形dp】

    没考虑可以连着两个不选--直接染色了 实际上是基环森林,对于每棵基环树,dfs找出一个环边,然后断掉这条边,分别对这条边的两端点做一边treedp,取max加进答案里 treedp是设f[u]为选u点 ...

  6. BZOJ - 3242 :快餐店 (基环树DP) 最小化半径

    题意:给定N点N边的无向连通图,现在让你在图中找一点作为餐厅,使得最远点距离这点最近. 思路:为了保留整数,我们求最小直径,最后去除2.  直径来源于两部分: 1,在外向树中: 那么就是树的直接,一棵 ...

  7. BZOJ 4883: [Lydsy1705月赛]棋盘上的守卫 最小生成树 + 建模

    Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置 ...

  8. 【BZOJ4883】 [Lydsy1705月赛]棋盘上的守卫(最小生成树,基环树)

    传送门 BZOJ Solution 考虑一下如果把行,列当成点,那么显然这个东西就是一个基环树对吧. 直接按照\(Kruscal\)那样子搞就好了. 代码实现 代码戳这里

  9. [BZOJ4883][Lydsy1705月赛]棋盘上的守卫[最小基环树森林]

    题意 有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价. \ ...

随机推荐

  1. js 技巧 (七)JS代码判断集锦(之一)

    JS代码判断集锦(之一) ~~~~~~~~~~~~~~~~~~ <script language="JavaScript"> function checkid(iden ...

  2. Linux命令学习(4):gzip压缩与解压

    版权声明:本文为博主原创文章,未经允许不得转载 引子 gzip是Linux系统中最常用也是高效的压缩压缩命令.早期Linux系统中主要使用compress命令压缩,得到后缀为“.Z”的压缩文件,但是后 ...

  3. python3.x Day6 paramiko

    python3 paramiko模块,用来进行远程操作linux服务器,利用的就是ssh #利用用户名,密码,进行连接 import paramiko #创建一个SSH对象 ssh=paramiko. ...

  4. assert.doesNotThrow()

    assert.doesNotThrow(block[, error][, message]) 断言 block 函数不会抛出错误.查阅 assert.throws() 了解更多详情. 当调用 asse ...

  5. Spring Boot 2 (三):Spring Boot 开源软件都有哪些?

    016年 Spring Boot 还没有被广泛使用,在网上查找相关开源软件的时候没有发现几个,到了现在经过2年的发展,很多互联网公司已经将 Spring Boot 搬上了生产,而使用 Spring B ...

  6. 13-看图理解数据结构与算法系列(Trie树)

    Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...

  7. [luoguP1033] 自由落体(模拟?)

    传送门 这不能算是数论题... 卡精度这事noip也做的出来.. 代码 #include <cmath> #include <cstdio> int n, ans; doubl ...

  8. Ubuntu 16.04安装ntopng流量监控软件

    ntop官方在2012年就已经不再更新,取代的是ntopng.ntopng具有Web页面,适合做网络管理监控软件.比如监控局域网内多台机器的上网情况等. 不过这个东西感觉不太准,最好的方案应该把安装n ...

  9. 我的arcgis培训照片11

    来自:http://www.cioiot.com/successview-546-1.html

  10. ajax 请求 get请求成功,post 404 not found

    今天在做express的一个ajax请求的时候发现get请求成功,post 就一直是 404 not found, 研究了半天 才发现是express 的请求方法做了限制,之前一直都是用的 app.g ...