【模板】最小生成树

题目传送门

解题思路

用LCT来维护最小生成树。

除了把各顶点作为节点外,每条边也都视为一个节点。对于要加入的边\(e\),检查其两顶点\(x\)和\(y\)是否在同一棵树中,如果不在,则让\(e\)连接\(x\)和\(y\)如果在一棵树中,则找到\(x\)到\(y\)的路径上最长的边,与\(e\)比较,如果\(e\)更小,则删掉那条边,再把\(e\)加入。只要维护一下最长的边的编号即可。

代码如下

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 300005;

int fa[N], ch[N][2], sta[N], maxx[N];
ll v[N];
bool rev[N]; inline bool get(int x)
{
return ch[fa[x]][1] == x;
} inline bool is_root(int x)
{
return (!fa[x] || ch[fa[x]][1] != x && ch[fa[x]][0] != x);
} inline void pushr(int x)
{
swap(ch[x][0], ch[x][1]);
rev[x] ^= 1;
} inline void push_up(int x)
{
int t = v[maxx[ch[x][1]]] > v[maxx[ch[x][0]]]? maxx[ch[x][1]]: maxx[ch[x][0]];
maxx[x] = v[t] > v[x]? t: x;
} inline void push_down(int x)
{
if(rev[x]){
pushr(ch[x][0]);
pushr(ch[x][1]);
rev[x] = 0;
}
} inline void rotate(int x)
{
int y = fa[x], z = fa[y];
int u = get(x);
ch[y][u] = ch[x][u^1], fa[ch[x][u^1]] = y;
if(!is_root(y))
ch[z][get(y)] = x;
fa[x] = z;
ch[x][u^1] = y, fa[y] = x;
push_up(y), push_up(x);
} inline void splay(int x)
{
int pos = 0;
sta[++pos] = x;
for(int i = x; !is_root(i); i = fa[i])
sta[++pos] = fa[i];
while(pos)
push_down(sta[pos--]);
while(!is_root(x)){
int y = fa[x];
if(!is_root(y))
get(x) == get(y)? rotate(y): rotate(x);
rotate(x);
}
} inline void access(int x)
{
for(int y = 0; x; y = x, x = fa[x])
splay(x), ch[x][1] = y, push_up(x);
} inline void make_root(int x)
{
access(x);splay(x);
pushr(x);
} inline void split(int x, int y)
{
make_root(x);
access(y);splay(y);
} inline int find_root(int x)
{
access(x);splay(x);
while(ch[x][0]){
push_down(x);
x = ch[x][0];
}
splay(x);
return x;
} int a[N], b[N]; void link(int id)
{
make_root(a[id]);
make_root(b[id]);
fa[a[id]] = id;
fa[b[id]] = id;
} int main()
{
int n, m;
scanf("%d%d", &n, &m);
int line = 0;
ll sum = 0;
for(int i = n + 1; i <= n + m; i ++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
a[i] = x, b[i] = y, v[i] = z;
maxx[i] = i;
make_root(x);
if(find_root(y) != x){
link(i);
++line;
sum += z;
}
else {
split(x, y);
int k = maxx[y];
if(v[k] > z){
splay(k);
fa[ch[k][0]] = fa[ch[k][1]] = 0;
ch[k][0] = ch[k][1] = 0;
link(i);
sum -= v[k] - z;
}
}
}
if(line == n - 1)
printf("%lld\n", sum);
else
printf("orz\n");
return 0;
}

洛谷P3366 【模板】最小生成树(LCT)的更多相关文章

  1. [洛谷P3366] [模板] 最小生成树

    存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...

  2. 最小生成树 & 洛谷P3366【模板】最小生成树 & 洛谷P2820 局域网

    嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...

  3. 洛谷P3366【模板】最小生成树-克鲁斯卡尔Kruskal算法详解附赠习题

    链接 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M&l ...

  4. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  5. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  6. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  7. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  8. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

  9. 洛谷.1919.[模板]A*B Problem升级版(FFT)

    题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 ...

  10. 洛谷.3803.[模板]多项式乘法(FFT)

    题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...

随机推荐

  1. golang的数据类型之浮点类型

    [root@node3 shangxuetang]# cat float.go package main import "fmt" //演示golang中小数类型使用func ma ...

  2. [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列)

    [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列) 题面 两个人玩游戏,共进行t轮,每人每轮从[-k,k]中选出一个数字,将其加到自己的总分中.已 ...

  3. vmware linux root密码破解

    centOS: 1.开机过程按上下箭头键,让系统不要进入到引导程序中, 2.按 'e' 进入到编辑模式 3.找到linux16开始的首行,在末尾加入'rw init=/bin/sh' (会出现修改密码 ...

  4. python 分析 知乎粉丝数据

    昨天花了一下午写了一个小爬虫,用来分析自己的粉丝数据.这个真好玩!今天帮了群里好多大V也爬了他们的数据.运行速度:每分钟5千粉丝以上.暂时先写成这样,这两天要准备补考,没有时间继续玩这个. 下次要改进 ...

  5. hdu6311 Cover (欧拉路径输出)

    hdu6311Cover 题目传送门 题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径. ...

  6. J Less taolu

    链接:https://ac.nowcoder.com/acm/contest/338/J来源:牛客网 题目描述 Less taolu, more sincerity. This problem is ...

  7. idea 配置maven web项目

    文章转自:https://www.cnblogs.com/weiqingfeng/p/9494914.html 步骤一:首先先创建一个project,上次我说过了创建一个project就是一个工作空间 ...

  8. .net 异步

    原文:https://www.cnblogs.com/wisdomqq/archive/2012/03/26/2412349.html 在说到异步前,先来理一下几个容易混淆的概念,并行.多线程.异步. ...

  9. activiti 5.22 表结构解析及清空流程运行测试数据

    1.结构设计 1.1.    逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: 'RE'表示repository(存储),RepositoryService接口所操作的 ...

  10. zabbix基础之环境搭建

    zabbix入门 环境部署 安装mysql #安装MySQL,官方的MySQL的repo源地址:http://repo.mysql.com/ #选择指定的MySQL版本,我这里选mysql5.7的版本 ...