BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)

【题目链接】 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;
}
时间: 2024-08-28 13:22:15

BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)的相关文章

【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

[BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个守卫,一个守卫 不能同时兼顾行列的防御.请计算控制整个棋盘的最小代价. Input 第一行包含两个正整数n,m(2<=n,m<=100000,n*m<=100000),分别表示棋盘的行数与列数. 接下来n行,每

[bzoj4883][Lydsy2017年5月月赛]棋盘上的守卫

来自FallDream的博客,未经允许,请勿转载, 谢谢. 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个守卫,一个守卫 不能同时兼顾行列的防御.请计算控制整个棋盘的最小代价. n*m<=10^5 费用流比较好想,把行和列拿出来,第i行向第j列连费用是a[i][j]的边,然后限制每行每列流量1即可. 但是费用流不是很科学(好像有人大力艹过了?),考虑优

bzoj 4836: [Lydsy2017年4月月赛]二元运算 -- 分治+FFT

4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec  Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) 使得 a_i  opt b_j=c . Input 第一行是一个整数 T (1≤T≤10) ,表示测试数据的组数. 对于每组测试数据: 第一行是三个整数 n,m,q (

BZOJ 4884 [Lydsy2017年5月月赛]太空猫(单调DP)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4884 [题目大意] 太空猫(SpaceCat)是一款画面精致.玩法有趣的休闲游戏, 你需要控制一只坐在迷你飞碟上的猫咪在太空里不断探索,让大家看看你能飞得多远. 游戏地图可以看成一个二维的网格图,上下是两段障碍物. 在游戏的一开始,太空猫位于地图最左边的下边界之上,且重力方向向下. 在每个时刻,你可以用手指点击屏幕,翻转重力的方向, 或者通过遥感控制太空猫往左或往右移动.每次翻转重力

【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)

4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 275  Solved: 87 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学

[Lydsy2017年4月月赛]抵制克苏恩

[Lydsy2017年4月月赛]抵制克苏恩 时间限制: 1 Sec  内存限制: 128 MB提交: 49  解决: 34[提交][状态][讨论版] 题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是因为对手使用了克苏恩这张牌,所

4832: [Lydsy2017年4月月赛]抵制克苏恩]【解题报告】

戳我 4832: [Lydsy2017年4月月赛]抵制克苏恩 时间限制: 1 Sec  内存限制: 128 MB提交: 752  解决: 289[提交][][] 题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是 因为对手使用

【BZOJ 4832】 [Lydsy2017年4月月赛] 抵制克苏恩 期望概率dp

打记录的题打多了,忘了用开维记录信息了......我们用f[i][j][l][k]表示已经完成了i次攻击,随从3血剩j个,2血剩l个,1血剩k个,这样我们求出每个状态的概率,从而求出他们对答案的贡献并加和,一开始我用的期望忘了转移的时候不能用1而要用概率...... #include <cstdio> #include <cstring> #define r register using namespace std; typedef long double LD; inline i

抵制克苏恩[Lydsy2017年4月月赛]

题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是因为对手使用了克苏恩这张牌,所以他想找到一些方法来抵御克苏恩.他去求助职业炉石传说玩家椎名真白,真白告诉他使用奴隶主这张牌就可以啦.如果你不明白我上面在说什么,不必担心,小Q同学会