[Luogu P4180][BJWC 2010]严格次小生成树
严格次小生成树,关键是“严格”,如果是不严格的其实只需要枚举每条不在最小生成树的边,如果得到边权和大于等于最小生成树的结束就行。原理就是因为Kruskal非常贪心,只要随便改一条边就能得到一个非严格的次小生成树。然而是严格的QAQ,于是得搞点别的东西来实现“严格”,维护个次大值就行。依次枚举每条边,如果这条边和加上这条边构成的环中最大的边边权相等,取次大值,否则取最大值。
参考代码:
#include<cstdio>
#include<algorithm>
#define ll long long
#include<iostream>
#define A(x) cout << #x << " " << x << endl;
#define qwq 900100
const ll inf = ;
using namespace std;
struct Node
{
ll u,v,val,nxt;
bool used;
} a[ * qwq],b[ * qwq];
ll head[qwq];
ll f[qwq];
ll find(ll x) {
if(x == f[x]) return x;
return f[x] = find(f[x]);
}
ll n,m,cnt;
void add(ll u,ll v,ll w) {
cnt++;
b[cnt].nxt = head[u];
head[u] = cnt;
b[cnt].val = w;
b[cnt].v = v;
}
bool cmp(Node a,Node b) {
return a.val < b.val;
}
ll ans = 0ll;
void kruskal() {
ll k = ;
for(ll i = ; i <= n; i++) f[i] = i;
for(ll i = ; i <= m; i++)
{
ll f1 = find(a[i].u);
ll f2 = find(a[i].v);
if(f1 != f2) {
f[f1] = f2;
k++;
ans += a[i].val;
add(a[i].u,a[i].v,a[i].val);
add(a[i].v,a[i].u,a[i].val);
a[i].used = ;
if(k == n - ) break;
}
}
}
ll fa[qwq][],dep[qwq];
ll maxx[qwq][],lmax[qwq][];
void dfs(ll u,ll pa) {
fa[u][] = pa;
for(int i = head[u]; i; i = b[i].nxt) {
ll v = b[i].v;
if(v == pa) continue;
dep[v] = dep[u] + 1ll;
maxx[v][] = b[i].val;
lmax[v][] = -inf;
dfs(v,u);
}
}
void max_set() {
for(ll i = ; i <= ; i++)
for(ll u = ; u <= n; u++) {
fa[u][i] = fa[fa[u][i - ]][i - ];
maxx[u][i] = max(maxx[u][i - ],maxx[fa[u][i - ]][i - ]);
lmax[u][i] = max(lmax[u][i - ],lmax[fa[u][i - ]][i - ]);
if(maxx[u][i - ] > maxx[fa[u][i - ]][i - ])
lmax[u][i] = max(lmax[u][i],maxx[fa[u][i - ]][i - ]);
else if(maxx[u][i - ] < maxx[fa[u][i - ]][i - ])
lmax[u][i] = max(lmax[u][i],maxx[u][i - ]);
}
}
ll lca(ll x,ll y) {
if(dep[x] < dep[y]) swap(x,y);
for(ll i = ; i >= ; i--)
if(dep[fa[x][i]] >= dep[y])
x = fa[x][i];
if(x == y) return x;
for(ll i = ; i >= ; i--)
if(fa[x][i] ^ fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
return fa[x][];
}
ll find_max(ll u,ll v,ll qaq) {
ll Ans = -inf;
for(ll i = ; i >= ; i--) {
if(dep[fa[u][i]] >= dep[v]) {
if(qaq != maxx[u][i])Ans = max(Ans,maxx[u][i]);
else Ans = max(Ans,lmax[u][i]);
u = fa[u][i];
}
}
return Ans;
}
int main()
{
scanf("%lld %lld",&n,&m);
for(ll i = ;i <= m;i++)
{
scanf("%lld %lld %lld",&a[i].u,&a[i].v,&a[i].val);
}
sort(a + ,a + + m,cmp);
kruskal();
lmax[][] = -inf;
dep[] = 1ll;
dfs(,-);
max_set();
ll answ = inf;
for(ll i = ; i <= m; i++)
{
if(!a[i].used)
{
ll u = a[i].u;
ll v = a[i].v;
ll d = a[i].val;
ll Lca = lca(u,v);
ll maxu = find_max(u,Lca,d);
ll maxv = find_max(v,Lca,d);
answ = min(answ,ans - max(maxu,maxv) + d);
}
}
printf("%lld",answ);
}
[Luogu P4180][BJWC 2010]严格次小生成树的更多相关文章
- 【Beijing 2010】 次小生成树
[题目链接] 点击打开链接 [算法] 首先,有一个结论 : 一定有一棵严格次小生成树是在最小生成树的基础上去掉一条边,再加上一条边 这个结论的正确性是显然的 我们先用kruskal算法求出最小生成树, ...
- 【luogu P4180 严格次小生成树[BJWC2010]】 模板
题目链接:https://www.luogu.org/problemnew/show/P4180 这个题卡树剖.记得开O2. 这个题inf要到1e18. 定理:次小生成树和最小生成树差距只有在一条边上 ...
- Luogu P4180 【模板】严格次小生成树[BJWC2010]
P4180 [模板]严格次小生成树[BJWC2010] 题意 题目描述 小\(C\)最近学了很多最小生成树的算法,\(Prim\)算法.\(Kurskal\)算法.消圈算法等等.正当小\(C\)洋洋得 ...
- 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)
洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...
- [Luogu] 次小生成树
https://www.luogu.org/problemnew/show/P4180#sub 严格次小生成树,即不等于最小生成树中的边权之和最小的生成树 首先求出最小生成树,然后枚举所有不在最小生成 ...
- P4180 【模板】严格次小生成树[BJWC2010]
P4180 [模板]严格次小生成树[BJWC2010] 倍增(LCA)+最小生成树 施工队挖断学校光缆导致断网1天(大雾) 考虑直接枚举不在最小生成树上的边.但是边权可能与最小生成树上的边相等,这样删 ...
- 洛谷P4180【Beijing2010组队】次小生成树Tree
题目描述: 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还 ...
- P4180 [BJWC2010]严格次小生成树
P4180 [BJWC2010]严格次小生成树 P4180 题意 求出一个无向联通图的严格次小生成树.严格次小生成树的定义为边权和大于最小生成树的边权和但不存在另一棵生成树的边权和在最小生成树和严格次 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
随机推荐
- 在Visual Studio 2017上配置Glut
在Visual Studio 2017上配置Glut 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 在Visual Studio 2017上配置并使用 ...
- 【模块04-大数据技术入门】02节-HDFS核心知识
分布式存储 (1) 5PB甚至更大的数据集怎么存储 ? 所有数据分块,每个数据块冗余存储在多台机器上(冗余可提高数据块高可用性).另外一台机器上启动一个管理所有节点.以及存储在各节点上面数据块的服务. ...
- ORACLESQL语句的优化
ORACLESQL语句的优化: 选择最有效率的表名顺序:应该选择记录条数最少的表作为基表! 因为Oracle解析器的处理顺序是从右至左的.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们. ...
- kafka实战kerberos
more /etc/krb5.conf [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log a ...
- 解决IntelliJ IDEA 创建Maven项目速度慢问题
IntelliJ IDEA 创建maven项目速度很慢,甚至卡住不动了. 原因 IDEA根据maven archetype的本质,其实是执行mvn archetype:generate命令,该命令执行 ...
- laravel整理笔记(一)
安装laravel5.8.3需要的环境 PHP >= 7.1.3 PHP OpenSSL 扩展 PHP PDO 扩展 PHP Mbstring 扩展 PHP Tokenizer 扩展 PHP X ...
- 重建二叉树[by Python]
题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2 ...
- Mac系统下Mysql存储数据报错 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value
比如如下mysql操作插入数据: const mysql = require('mysql'); /* createConnection方法创建一个表示与Mysql数据库服务器之间连接的 Connec ...
- Linux内核入门到放弃-内核活动-《深入Linux内核架构》笔记
中断 中断类型 同步中断和异常.这些由CPU自身产生,针对当前执行的程序 异步中断.这是经典的中断类型,由外部设备产生,可能发生在任意时间. 在退出中断中,内核会检查下列事项. 调度器是否应该选择一个 ...
- spring boot到底帮我们做了那些事?
一.前言 上一篇介绍了注解,也是为这一篇做铺垫,传统的都是通过配置文件来启动spring,那spring boot到底是做了什么能让我们快速开发昵? 二.启动原理 看下程序启动的入口, ...