BZOJ 1977: [BeiJing2010组队]次小生成树 Tree 倍增 最小生成树
好吧我太菜了又调了一晚上。。。QAQ
先跑出最小生成树,标记树边,再用树上倍增的思路,预处理出:
f[u][i] :距离u为2^i的祖先
h[u][i][0/1] :距u点在2^i范围内的最长边和次长边
然后枚举每一条非树边(u,v),会与原先的最小生成树构成一个环,而之前预处理出的数据可以快速找到(u,v)在最小生成树上的最大和次大边,来更新答案
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define int long long
#define R register int
using namespace std;
inline int g() {
R ret=,fix=;register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
struct node{int u,v,w;bool operator <(const node & y) const { return w<y.w;}}a[];
struct edge{int v,w,nxt;}e[];
int n,m,cnt,mx,mmx,mn=0x3f3f3f3f,ans,tot;
int fir[],f[][],h[][][],fa[],d[];
bool tr[];
inline void add(int u,int v,int w) {e[++cnt].v=v,e[cnt].nxt=fir[u],e[cnt].w=w,fir[u]=cnt;}
inline void ins(int u,int v,int w) {add(u,v,w),add(v,u,w);}
inline int getf(int x) {return x==fa[x]?x:fa[x]=getf(fa[x]);}
inline void dfs(int u,int fa) {
for(R i=fir[u];i;i=e[i].nxt) {
R v=e[i].v; if(v==fa) continue;
f[v][]=u,h[v][][]=e[i].w,d[v]=d[u]+;
for(R i=;d[v]>=(<<i);++i) {
f[v][i]=f[f[v][i-]][i-];
h[v][i][]=max(h[v][i-][],h[f[v][i-]][i-][]);
if(h[v][i-][]==h[f[v][i-]][i-][])
h[v][i][]=max(h[v][i-][],h[f[v][i-]][i-][]);
else {
h[v][i][]=min(h[v][i-][],h[f[v][i-]][i-][]);
h[v][i][]=max(h[v][i-][],h[v][i][]);
h[v][i][]=max(h[v][i][],h[f[v][i-]][i-][]);
}
} dfs(v,u);
}
}
inline int lca(int u,int v) {
if(d[u]<d[v]) swap(u,v); R lim=log2(d[u])+;
for(R j=lim;j>=;--j) if(d[f[u][j]]>=d[v]) u=f[u][j];
if(u==v) return u;
for(R j=lim;j>=;--j) if(f[u][j]!=f[v][j]) u=f[u][j],v=f[v][j];
return f[u][];
}
inline void calc(int u,int fa,int w) {
mx=,mmx=; R lim=log2(d[u]-d[fa])+;
for(R i=lim;i>=;--i) if(d[u]-d[fa]>=(<<i)){
if(h[u][i][]>mx) mmx=mx,mx=h[u][i][];
mx=max(h[u][i][],mx); mmx=max(mmx,h[u][i][]),u=f[u][i];
}
if(mx!=w) mn=min(mn,w-mx); else mn=min(mn,w-mmx);
}
signed main() {
n=g(),m=g();
for(R i=;i<=n;++i) fa[i]=i;
for(R i=;i<=m;++i) a[i].u=g(),a[i].v=g(),a[i].w=g();
sort(a+,a+m+);
for(R i=;i<=m&&tot<n;++i) {
R uf=getf(a[i].u),vf=getf(a[i].v);
if(uf==vf) continue;
fa[uf]=vf; ans+=a[i].w; tr[i]=true;
ins(a[i].u,a[i].v,a[i].w); ++tot;
} dfs(,);
for(R i=;i<=m;++i) if(!tr[i]) {
R L=lca(a[i].u,a[i].v);
calc(a[i].u,L,a[i].w); calc(a[i].v,L,a[i].w);
} printf("%lld\n",ans+mn);
}
2019.04.09
BZOJ 1977: [BeiJing2010组队]次小生成树 Tree 倍增 最小生成树的更多相关文章
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...
- BZOJ 1977[BeiJing2010组队]次小生成树 Tree - 生成树
描述: 就是求一个次小生成树的边权和 传送门 题解 我们先构造一个最小生成树, 把树上的边记录下来. 然后再枚举每条非树边(u, v, val),在树上找出u 到v 路径上的最小边$g_0$ 和 严格 ...
- 【刷题】BZOJ 1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- bzoj 1977 [BeiJing2010组队]次小生成树 Tree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1977 kruscal别忘了先按边权sort.自己觉得那部分处理得还挺好的.(联想到之前某题的 ...
- 1977: [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 5168 Solved: 1668[S ...
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
[BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...
- 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
随机推荐
- jstl <c:url>标签
标签作用是将一个URL地址格式化为一个字符串,并且保存在一个变量当中.它具有URL自动重写功能.value指定的URL可以是当前工程的一个URL地址,也可以是其他web工程的URL.但是这时需要con ...
- Kafka0.7运行时报错 kafka/javaapi/consumer/ConsumerConnector : Unsupported major.minor version 51.0 解决
目前中央库中 org.apache.kafka 是用jdk1.7编译的, 故跑在1.6的jvm中会报错 解决方案: 1. 下载kafka源码, 本地sbt进行install, 编译前 java -ve ...
- BZOJ 4582 [Usaco2016 Open]Diamond Collector:贪心【相差不超过k】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4582 题意: 给你n个数. 让你将其中的一些数放入两个不同的集合中,并保证同一集合内两两元 ...
- BZOJ 1724 [Usaco2006 Nov]Fence Repair 切割木板:贪心 优先队列【合并果子】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1724 题意: 你要将一块长木板切成n段,长度分别为a[i](长木板的长度 = ∑ a[i] ...
- C#多线程编程介绍——使用thread、threadpool、timer
C#多线程编程介绍——使用thread.threadpool.timer 在system.threading 命名空间提供一些使得能进行多线程编程的类和接口,其中线程的创建有以下三种方法:thread ...
- Ajax动态切换按钮
function changeAjax(str, obj) { var idx = $(obj).parent().parent().index(); if(confirm('确定执行操作么?')) ...
- CodeForces - 592D: Super M(虚树+树的直径)
Ari the monster is not an ordinary monster. She is the hidden identity of Super M, the Byteforces’ s ...
- k8s-应用快速入门(ma)
[root@k8s-master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 deplo ...
- PageMethods
主要是用到ScriptManger,老知识Mark一下,ScriptManager要EnablePageMethods="true" 后台 using System.Web.Scr ...
- tyvj1015公路乘车——DP
题目:http://www.joyoi.cn/problem/tyvj-1015 代码如下: #include<iostream> #include<cstdio> using ...