「CSA72」MST
「CSA72」MST
题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改,每次将一个矩形的权值加上 \(w\) ,求出最后这张完全图的最小生成树的边权和。\(n,m \leq 100000\)。
解题思路:用 Borůvka 求最小生成树,每一轮求出每一个点所在联通块向外连的一条边权最小的边,并用线段树+扫描线维护最小值以及最小值所在的联通块编号。为了找到不在同一个联通块内的边权最小的边,所以额外记一个次小值,并时刻保证次小值所在的联通块编号与最小值不是同一个,那么要连出去的最小的边一定在这两者之间,总复杂度 \(O(nlog^2n)\)。
code
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf ((ll)(1e16))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T & x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define par pair<ll, ll>
#define fi first
#define se second
const int N = 100005;
struct chino{ int t, l, r, w; } q[N<<2];
int fa[N], n, m, tot, cnt; ll ans;
par tmp[N];
inline int ask(int x){ return x == fa[x] ? x : fa[x] = ask(fa[x]); }
struct Node{
int id[2]; ll val[2];
inline Node(){ val[0] = val[1] = inf, id[0] = id[1] = 0; }
inline Node operator + (const int &w){
Node res = *this;
return res.val[0] += w, res.val[1] += w, res;
}
inline Node operator + (const Node &A){
Node res, rhs;
res = (val[0] < A.val[0] ? *this : A);
rhs = (val[0] < A.val[0] ? A : *this);
for(int i = 0; i < 2; i++)
if(ask(rhs.id[i]) != ask(res.id[0]) && rhs.val[i] < res.val[1])
res.val[1] = rhs.val[i], res.id[1] = rhs.id[i];
return res;
}
};
namespace Seg{
#define lson (u << 1)
#define rson (u << 1 | 1)
#define mid (l + r >> 1)
Node mn[N<<2]; ll tag[N<<2];
inline void build(int u, int l, int r){
tag[u] = 0;
if(l == r){
mn[u].val[0] = 0, mn[u].val[1] = inf;
mn[u].id[0] = l, mn[u].id[1] = 0; return;
}
build(lson, l, mid), build(rson, mid + 1, r);
mn[u] = mn[lson] + mn[rson];
}
inline void pushdown(int u){
if(!tag[u]) return;
mn[lson] = mn[lson] + tag[u], mn[rson] = mn[rson] + tag[u];
tag[lson] += tag[u], tag[rson] += tag[u], tag[u] = 0;
}
inline void change(int u, int l, int r, int L, int R, ll w){
if(l >= L && r <= R) return (void) (mn[u] = mn[u] + w, tag[u] += w);
pushdown(u);
if(L <= mid) change(lson, l, mid, L, R, w);
if(mid < R) change(rson, mid + 1, r, L, R, w);
mn[u] = mn[lson] + mn[rson];
}
}
inline void Bruasolve(){
Seg::build(1, 1, n);
for(register int i = 1; i <= n; i++) tmp[i].fi = inf, tmp[i].se = 0;
int p = 1;
for(register int i = 1; i <= n; i++){
while(p <= cnt && q[p].t == i)
Seg::change(1, 1, n, q[p].l, q[p].r, q[p].w), p++;
Node x = Seg::mn[1];
par now = (ask(x.id[0]) != ask(i)) ? make_pair(x.val[0], x.id[0]) : make_pair(x.val[1], x.id[1]);
if(now.fi < tmp[ask(i)].fi) tmp[ask(i)] = now;
}
for(register int i = 1; i <= n; i++) if(fa[i] == i){
if(ask(tmp[i].se) != i && tmp[i].se) tot++, ans += tmp[i].fi, fa[ask(tmp[i].se)] = i;
}
}
inline bool cmp(const chino &A, const chino &B){ return A.t < B.t; }
signed main(){
read(n), read(m);
for(int i = 1, X1, X2, Y1, Y2, w; i <= m; i++){
read(X1), read(X2), read(Y1), read(Y2), read(w);
q[++cnt] = ((chino){X1, Y1, Y2, w});
q[++cnt] = ((chino){X2 + 1, Y1, Y2, -w});
q[++cnt] = ((chino){Y1, X1, X2, w});
q[++cnt] = ((chino){Y2 + 1, X1, X2, -w});
}
sort(q + 1, q + cnt + 1, cmp);
for(int i = 1; i <= n; i++) fa[i] = i;
while(tot < n - 1) Bruasolve(); cout << ans << endl;
return 0;
}
「CSA72」MST的更多相关文章
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
- 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance
提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...
随机推荐
- js中字符串和json数组的相互转换
//示例 var a={"name":"tom","sex":"男","age":"24& ...
- LintCode题解之子树
思路: 最简单的方法,依次遍历比较就可以了. AC代码: /** * Definition of TreeNode: * public class TreeNode { * public int va ...
- WordPress浏览数插件的安装使用
插件安装很容易,但是和大多插件都一样,安装后需要调用代码才能显示,我安装后,也调用了.但是就是不显示,后来才发现,我从其他地方复制过来的代码,函数是中文的单引号,这样致使函数失效,注意代码中参数的引号 ...
- OkHttp与Cookie及Cookie的持久化
http://blog.csdn.net/u011150924/article/details/52780931 http://blog.csdn.net/chen19960724/article/d ...
- Perl6多线程2: Promise new/keep/bread/status/result
来源于个人理解的翻译. 创建一个 promise: my $p = Promise.new; 可以打印运行 的Promise 状态: my $p = Promise.new(); $p.then({s ...
- 【swupdate文档 四】SWUpdate:使用默认解析器的语法和标记
SWUpdate:使用默认解析器的语法和标记 介绍 SWUpdate使用库"libconfig"作为镜像描述的默认解析器. 但是,可以扩展SWUpdate并添加一个自己的解析器, ...
- 64_p6
polkit-kde-5.10.1-1.fc26.x86_64.rpm 12-Jun-2017 13:45 84854 polkit-libs-0.113-8.fc26.i686.rpm 13-Apr ...
- HDU 6187 Destroy Walls (对偶图最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6187 题意:有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一 ...
- tp 框架 利用反射实现对象调用方法
<?php class Person{ public $name="xiaoming"; function say(){ echo "i am ".$th ...
- java版云笔记(八)之关联映射
Mybatis关联映射 通过数据库对象之间的关联关系,反映到到实体对象之间的引用. 加载多个表中的关联数据,封装到我们的实体对象中. 当业务对数据库进行关联查询. 关联 <association ...