[BZOJ 4883][Lydsy2017年5月月赛]棋盘上的守卫:最小生成树
2017-05-06 14:24
435 查看
点击这里查看原题
对于每个点,可以选择守横向或者守纵向。每行为一个点,每列为一个点,于是对于w[i][j],在i与j+n之间连一条权值为w[i][j]的边,然后去求带一个环的最小生成树,这样刚好有n+m条边,而且每条边都连了一个横行和一个纵行,也就是每条边代表了一个守卫。
对于每个点,可以选择守横向或者守纵向。每行为一个点,每列为一个点,于是对于w[i][j],在i与j+n之间连一条权值为w[i][j]的边,然后去求带一个环的最小生成树,这样刚好有n+m条边,而且每条边都连了一个横行和一个纵行,也就是每条边代表了一个守卫。
/* User:Small Language:C++ Problem No.:4883 */ #include<bits/stdc++.h> #define ll long long using namespace std; const int M=1e5+5; int n,m,tot,pre[M]; bool v[M]; ll ans; struct edge{ int u,v,w; bool operator<(const edge b)const{ return w<b.w; } }e[M]; int get(int x){ return x==pre[x]?x:pre[x]=get(pre[x]); } int main(){ freopen("data.in","r",stdin);// scanf("%d%d",&n,&m); for(int i=1;i<=n+m;i++) pre[i]=i; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int z; scanf("%d",&z); e[++tot]=(edge){i,j+n,z}; } } sort(e+1,e+tot+1); for(int i=1;i<=tot;i++){ int x=get(e[i].u),y=get(e[i].v); if(v[x]&&v[y]) continue; if(x!=y){ v[y]|=v[x]; pre[x]=y; } else v[x]=1; ans+=e[i].w; } printf("%lld\n",ans); return 0; }
相关文章推荐
- BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)
- bzoj 4883: [Lydsy2017年5月月赛]棋盘上的守卫 最小生成树
- 【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林
- bzoj4883 [Lydsy2017年5月月赛]棋盘上的守卫
- bzoj 4883: [Lydsy2017年5月月赛]棋盘上的守卫
- BZOJ4883: [Lydsy2017年5月月赛]棋盘上的守卫
- 【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法
- BZOJ4883 [Lydsy2017年5月月赛]棋盘上的守卫
- [bzoj4883][Lydsy2017年5月月赛]棋盘上的守卫
- 4883: [Lydsy2017年5月月赛]棋盘上的守卫
- BZOJ4883 [Lydsy2017年5月月赛]棋盘上的守卫
- [bzoj4881][Lydsy2017年5月月赛]线段游戏
- bzoj 4881: [Lydsy2017年5月月赛]线段游戏 树状数组+set
- bzoj4878: [Lydsy2017年5月月赛]挑战NP-Hard
- BZOJ 4881 [Lydsy2017年5月月赛] 二分图染色+线段树
- bzoj4886 [Lydsy2017年5月月赛]叠塔游戏
- BZOJ 4881: [Lydsy2017年5月月赛]线段游戏
- bzoj 4878 [Lydsy2017年5月月赛]挑战NP-Hard(dfs)
- bzoj5049 [Lydsy2017年5月月赛]导航系统
- bzoj4885: [Lydsy2017年5月月赛]长方体