• 题目描述
  • 吐槽一下
  • 思考人生
  • 安利一发
题目描述

有一天,pqq准备去给×i×准备礼物,他有一些礼品准备包装一下,他用线将这些礼物连在一起,不同的礼物因为风格不同所以连接它们需要不同价值的线。风格差异越大,价格越大(所以两个礼物之间只有一种连接价格),当然有些礼物实在太不友好,所以有些礼物无法相连。pqq打算把所有礼物打包在一起,他不准备花太多钱,但更不想花最少的钱(免得被拒绝)。所以他想知道第二便宜的包装方案(可重复,pqq会认为这是天命并直接选用最小代价来包装礼物),同时,他还想知道最小的包装代价以向×i×进行炫耀。但是由于pqq不够心灵手巧,所以他准备找你来帮他计算答案。

吐槽一下

这个xix是谁?

思考人生

所以这个题就是裸的非严格次小生成树了.
所谓非严格次小生成树,就是满足生成树道路总长≥≥\geq最小生成树的总长且总长最小的那个生成树.
我们不妨思考.

/*
那么这题是有两种写法的.
首先最容易想到的是枚举每一条树边,把这条边去掉重跑最小生成树,复杂度n*m,非常优越.
剩下就是枚举每一条非树边,求这条边连接的两点在树上最大边权,减掉这个加上那个取最小值.
求这个最大边权可以倍增dp,这个我不会,我用了树剖来写,复杂度提升了一个log,不过问题不大.
那么这题便迎刃而解.我太菜了竟然调了一天才写出来.
*/
#include<bits/stdc++.h>
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){int x=0,f=1;char c=gc();for (;!isdigit(c);c=gc()) f^=c=='-';for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');return f?x:-x;}
template <typename mitsuha>
inline bool read(mitsuha &x){x=0;int f=1;char c=gc();for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';if (!~c) return 0;for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');return x=f?x:-x,1;}
template <typename mitsuha>
inline int write(mitsuha x){if (!x) return 0&pc(48);if (x<0) x=-x,pc('-');int bit[20],i,p=0;for (;x;x/=10) bit[++p]=x%10;for (i=p;i;--i) pc(bit[i]+48);return 0;}
inline char fuhao(){char c=gc();for (;isspace(c);c=gc());return c;}
}using namespace chtholly;
using namespace std;
const int yuzu=2e5;
const ll inf=1e16;
typedef int fuko[yuzu|10];
int n=read(),m=read(),cnt,ecnt;
fuko vis,head;
struct node{
int u,v,cost;
void rd(){u=read(),v=read(),cost=read();}
bool operator <(const node &b){return cost<b.cost;}
}b[yuzu|10];
struct dsu{
fuko fa;
void init(int n){for (int i=1;i<=n;++i) fa[i]=i;}
int find(int x){return fa[x]^x?fa[x]=find(fa[x]):x;}
int mg(int u,int v){int fu=find(u),fv=find(v);return fu^fv?fa[fu]=fv,1:0;}
}my_;
struct edge{int fr,to,cost,next;}e[yuzu<<1|13];
void add(int u,int v,int c){e[++ecnt]=edge{u,v,c,head[u]},head[u]=ecnt;}
ll mst;
ll getmst(){
for (int i=1;i<=m;++i){int u=b[i].u,v=b[i].v,c=b[i].cost;if (my_.mg(u,v)){vis[i]=1,mst+=c;add(u,v,c),add(v,u,c);}}return mst;
}namespace tree_chain_splitting{
fuko fa,son,sz,dep,ord,dfn,top,a;void dfs1(int u,int f){sz[u]=1,dep[u]=dep[fa[u]=f]+1; for (int i=head[u];i;i=e[i].next){int v=e[i].to;if (v^f){dfs1(v,u),sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v; }}}
void dfs2(int u,int _top){top[u]=_top,dfn[ord[++cnt]=u]=cnt;if (son[u]) dfs2(son[u],_top);for (int i=head[u];i;i=e[i].next){int v=e[i].to;if (v^fa[u]&&(v^son[u])) dfs2(v,v);}}typedef ll karen[yuzu<<2|13];
struct segtree{
#define le rt<<1
#define ri le|1
#define ls le,l,mid
#define rs ri,mid+1,r
karen da;
void build(int rt=1,int l=1,int r=n){if (l==r) da[rt]=a[l];else{int mid=l+r>>1;build(ls),build(rs);da[rt]=max(da[le],da[ri]);}}
ll query(int ql,int qr,int rt=1,int l=1,int r=n){if (ql>r||qr<l) return -inf;if (ql<=l&&qr>=r) return da[rt];int mid=l+r>>1;return max(query(ql,qr,ls),query(ql,qr,rs));}
}llx;void preedge(){for (int i=1;i<=m;++i) if (vis[i]){int u=b[i].u,v=b[i].v;if (dep[u]>dep[v]) swap(u,v);a[dfn[v]]=b[i].cost;}}ll query(int u,int v){ll ans=-inf;for (;top[u]^top[v];u=fa[top[u]]){if (dep[top[u]]<dep[top[v]]) swap(u,v);ans=max(ans,llx.query(dfn[top[u]],dfn[u]));} if (dep[u]>dep[v]) swap(u,v);return max(ans,llx.query(dfn[u]+1,dfn[v]));}int main(){int i;dfs1(1,0),dfs2(1,1);preedge(),llx.build();ll zxy=inf;for (i=1;i<=m;++i) if (!vis[i]){int u=b[i].u,v=b[i].v;zxy=min(zxy,mst-query(u,v)+b[i].cost);}write(zxy);}
}int main(){
int i,j;
my_.init(n);
for (i=1;i<=m;++i) b[i].rd();
sort(b+1,b+m+1);
write(getmst()),p32;
tree_chain_splitting::main();
}

谢谢大家.

安利一发

倍增写法神仙的博客,学不来.

非严格次小生成树 pqq的礼物相关推荐

  1. XJOI 3629 非严格次小生成树(pqq的礼物)

    题目描述: 有一天,pqq准备去给×i×准备礼物,他有一些礼品准备包装一下,他用线将这些礼物连在一起,不同的礼物因为风格不同所以连接它们需要不同价值的线.风格差异越大,价格越大(所以两个礼物之间只有一 ...

  2. 【POJ1679】The Unique MST(非严格次小生成树)

    problem 给出一个连通无向图,判断它的最小生成树是否唯一 如果唯一,输出生成树的大小,否则输出"Not Unique!" solution 直接求非严格次小生成树 如果次小生 ...

  3. 非严格次小生成树+严格次小生成树

    非严格次小生成树+严格次小生成树 非严格次小生成树:首先使用最小生成树算法将最小生成树求出来,将生成树建图,然后用倍增维护树上的最大值. 考虑将所有的非树边一次加入最小生成树,并将新边与最小生成树形成 ...

  4. 一棵树的生成树有几颗_次小生成树(树剖,生成树)

    生成树的概念: 在一个无向图中,设顶点数为\(n\),取其中\(n-1\)条边并使所有点相连,所得到的一棵树即为生成树. 最小生成树: 如果还没有接触过生成树的同学,欢迎戳->最小生成树详解 次 ...

  5. 次小生成树(Prim + Kruaskal)

    问题引入: 我们先来回想一下生成树是如何定义的,生成树就是用n - 1条边将图中的所有n个顶点都连通为一个连通分量,这样的边连成子树称为生成树. 最小生成树很明显就是生成树中权值最小的生成树,那么我们 ...

  6. (luogu4180) [Beijing2010组队]次小生成树Tree

    严格次小生成树 首先看看如果不严格我们怎么办. 非严格次小生成树怎么做 由此,我们发现一个结论,求非严格次小生成树,只需要先用kruskal算法求得最小生成树,然后暴力枚举非树边,替换路径最大边即可. ...

  7. 最小生成树、次小生成树

    一.最小生成树 说到生成树首先要解释一下树,树是一个联通的无向无环图,多棵树的集合则被称为森林. 因此,树具有许多性质: 1.两点之间的路径是唯一的. 2.边数等于点数减一. 3.连接任意两点都会生成 ...

  8. 模板 - LCA最近公共祖先(倍增法、Tarjan、树上差分、LCA优化的次小生成树)

    整理的算法模板合集: ACM模板 注意x和y的LCA可以是x或者y本身 一.LCA的在线倍增算法 /*给定一棵包含 n个节点的有根无向树,有 m个询问,每个询问 给出了一对节点的编号 x和 y,询问 ...

  9. 解题报告:luogu P4180 [BJWC2010]严格次小生成树(次小生成树、倍增LCA优化、O(mlogn) )

    P4180 [BJWC2010]严格次小生成树 次小生成树有两种,一种是不严格次小生成树,也就是可以数值上等于最小生成树,一种是严格次小生成树,是权值严格大于最小生成树,两种求法大同小异. 方法2在严 ...

最新文章

  1. 编程题:两个数比较大小,之后用变量t互换。
  2. SqlDataSource 執行資料篩選
  3. SAP_常用业务数据表
  4. linux开机启动详细流程图
  5. 二十、Java基础--------IO流之其他对象
  6. nginx-rtmp一些指令
  7. 计算机显示去掉拼音分类,win8系统取消电脑文件显示以字母数字拼音分组的操作办法...
  8. 青岛著名地标“石老人”坍塌!数字化三维重建助力景观修复!
  9. c语言键盘符号大全,求c语言各种符号 并且意义。。在键盘上没有的 如何打?...
  10. 正则表达式 不含指定字符串
  11. 安装青龙面板(不用购买服务器即可薅羊毛)Ubuntu
  12. 初始化Weex项目遇到的问题记录
  13. Veristand制作Custom Device全网最详细教程
  14. Android Jetpack架构组件之Navigation
  15. Linux内核源代码获取教程
  16. 图书推荐:SQL Server 2012 T-SQL基础教程 Itzik Ben-Gan
  17. 20200509视频面试
  18. java 符号乱码怎么办_java字符乱码怎么办
  19. ModStartCMS v2.6.0 用着真得劲,头发也浓密了
  20. PrintWriter的使用方法

热门文章

  1. 索尼的hlg是什么_索尼HLG的拍摄使用方法
  2. 长尾词挖掘-长尾词挖掘工具-长尾关键词挖掘软件
  3. 7-33 地下迷宫探索 (30 分)
  4. web前端——浏览器兼容问题
  5. 欧盟边检AI测谎仪上线了,第一天就差点让记者进了小黑屋
  6. 【HFSS】有限大阵列FA-DDM仿真
  7. 社交类App如何防黑产垃圾用户?
  8. vincent歌曲翻译 很美很美很美
  9. 高等教育学:教学组织形式与教学工作基本环节
  10. PNAS | 香港理工李向东等揭示全球空气细菌群落与地球微生物组和人类活动的互作...