小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:(value(e)表示边e的权值) \sum_{e \in E_M}value(e)<\sum_{e \in E_S}value(e)∑e∈EM​​value(e)<∑e∈ES​​value(e)

这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

输入输出格式

输入格式:

第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

输出格式:

包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

输入输出样例

输入样例#1:

  1. 5 6
  2. 1 2 1
  3. 1 3 2
  4. 2 4 3
  5. 3 5 4
  6. 3 4 3
  7. 4 5 6
输出样例#1: 复制

  1. 11

说明

数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

跑个最小生成树然后LCA维护路径最大和次大(严格)边即可,利用了最小生成树的环性质。

(我就想请问出题人忘了给边排序是怎么能过样例hhhh,mdzz查错了一个点最后发现没给边排序)

code:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define maxn 100005
  4. using namespace std;
  5. ll base=0;
  6. struct lines{
  7. int u,v,w;
  8. bool operator <(const lines &U)const{
  9. return w<U.w;
  10. }
  11. }l[maxn*3];
  12. struct node{
  13. int m,cm;
  14. node operator +(const node &u)const{
  15. node r;
  16. r.m=max(m,u.m);
  17. r.cm=max(cm,u.cm);
  18. if(m<r.m) r.cm=max(r.cm,m);
  19. if(u.m<r.m) r.cm=max(r.cm,u.m);
  20. return r;
  21. }
  22. };
  23. const int inf=1e9;
  24. bool choose[maxn*3];
  25. int ci[30],ans=inf;
  26. int to[maxn*2],ne[maxn*2];
  27. int val[maxn*2],cnt=0,n,m;
  28. int f[maxn][20];
  29. node g[maxn][20];
  30. int hd[maxn],p[maxn],dep[maxn];
  31.  
  32. int ff(int x){
  33. return p[x]==x?x:(p[x]=ff(p[x]));
  34. }
  35.  
  36. inline void add(lines e){
  37. to[++cnt]=e.v,ne[cnt]=hd[e.u],val[cnt]=e.w,hd[e.u]=cnt;
  38. to[++cnt]=e.u,ne[cnt]=hd[e.v],val[cnt]=e.w,hd[e.v]=cnt;
  39. }
  40.  
  41. inline void kruscal(){
  42. for(int i=1;i<=n;i++) p[i]=i;
  43. int fa,fb,tot=0;
  44. sort(l+1,l+m+1);
  45.  
  46. n--;
  47. for(int i=1;i<=m;i++){
  48. fa=ff(l[i].u),fb=ff(l[i].v);
  49. if(fa!=fb){
  50. tot++,choose[i]=1;
  51. base+=(ll)l[i].w;
  52. add(l[i]),p[fa]=fb;
  53. if(tot==n) break;
  54. }
  55. }
  56. n++;
  57. }
  58.  
  59. void dfs(int x,int fa){
  60. for(int i=1;ci[i]<=dep[x];i++){
  61. g[x][i]=g[x][i-1]+g[f[x][i-1]][i-1];
  62. f[x][i]=f[f[x][i-1]][i-1];
  63. }
  64.  
  65. for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){
  66. dep[to[i]]=dep[x]+1;
  67. f[to[i]][0]=x;
  68. g[to[i]][0]=(node){val[i],0};
  69. dfs(to[i],x);
  70. }
  71. }
  72.  
  73. inline node LCAMAX(int x,int y){
  74. if(dep[x]<dep[y]) swap(x,y);
  75. int dt=dep[x]-dep[y];
  76. node an=(node){0,0};
  77. for(int i=0;ci[i]<=dt;i++) if(ci[i]&dt){
  78. an=an+g[x][i];
  79. x=f[x][i];
  80. }
  81.  
  82. if(x==y) return an;
  83.  
  84. int s=log(dep[x])/log(2)+1;
  85. for(;s>=0;s--){
  86. if(ci[s]>dep[x]) continue;
  87. if(f[x][s]!=f[y][s]){
  88. an=an+g[x][s]+g[y][s];
  89. x=f[x][s],y=f[y][s];
  90. }
  91. }
  92.  
  93. return an+g[x][0]+g[y][0];
  94. }
  95.  
  96. inline void solve(){
  97. dep[1]=0;
  98. dfs(1,0);
  99.  
  100. node tmp;
  101. for(int i=1;i<=m;i++) if(!choose[i]){
  102. tmp=LCAMAX(l[i].u,l[i].v);
  103. // printf("%d %d %d\n",i,tmp.m,tmp.cm);
  104. if(tmp.m<l[i].w) ans=min(ans,l[i].w-tmp.m);
  105. else ans=min(ans,l[i].w-tmp.cm);
  106. }
  107. }
  108.  
  109. int main(){
  110. ci[0]=1;
  111. for(int i=1;i<=20;i++) ci[i]=ci[i-1]<<1;
  112. scanf("%d%d",&n,&m);
  113. for(int i=1;i<=m;i++) scanf("%d%d%d",&l[i].u,&l[i].v,&l[i].w);
  114.  
  115. kruscal();
  116. solve();
  117.  
  118. cout<<(ll)ans+base<<endl;
  119. return 0;
  120. }

  

[Beijing2010组队]次小生成树Tree的更多相关文章

  1. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  2. 1977: [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...

  3. 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增

    [BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...

  4. [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 5168  Solved: 1668[S ...

  5. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  6. 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

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

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

  8. BZOJ 1977[BeiJing2010组队]次小生成树 Tree - 生成树

    描述: 就是求一个次小生成树的边权和 传送门 题解 我们先构造一个最小生成树, 把树上的边记录下来. 然后再枚举每条非树边(u, v, val),在树上找出u 到v 路径上的最小边$g_0$ 和 严格 ...

  9. 【刷题】BZOJ 1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

  10. 【bzoj1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+权值线段树合并

    题目描述 求一张图的严格次小生成树的边权和,保证存在. 输入 第一行包含两个整数N 和M,表示无向图的点数与边数. 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z ...

随机推荐

  1. Nova 如何统计 OpenStack 资源

    1.云计算的本质在于将硬件资源软件化,以达到快速按需交付的效果,最基本的计算.存储和网络基础元素并没有因此改变.就计算而言,CPU.RAM 和 DISK等依旧是必不可少的核心资源. 从源代码和数据库相 ...

  2. [C++] 拓展属性

    inline函数 函数重载 占位参数和默认参数 /*__________________________________________________________________ 背景: C++ ...

  3. jmeter的build.xml

    <?xml version="1.0"?><!--   Licensed to the Apache Software Foundation (ASF) unde ...

  4. ZOJ 1081 Points Within | 判断点在多边形内

    题目: 给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部 题解: 网上有两种方法,这里写一种:射线法 大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方 ...

  5. Codeforces Round #306 (Div. 2) 550A Two Substrings

    链接:http://codeforces.com/contest/550/problem/A 这是我第一次玩cf这种比赛,前面做了几场练习,觉得div2的前面几个还是比较水的. 所以看到这道题我果断觉 ...

  6. 牛客 2018NOIP 模你赛2 T2 分糖果 解题报告

    分糖果 链接:https://www.nowcoder.com/acm/contest/173/B 来源:牛客网 题目描述 \(N\) 个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们. 从某个 ...

  7. js常用数组去重

    // ES6 function unique (arr){ const seen = new Map() return arr.filter((a) => !seen.has(a) && ...

  8. ES6--javascript判断一个字符串是否存在另一个字符串中

    es5中我们经常使用indexof()方法来判断一个字符串是否包含另外一个字符串中. 如果存在则返回匹配到的第一个索引值.如果没有则返回 -1.所以,判断一个字符串是否包含另外一个字符串中只需要判断是 ...

  9. 看得懂的区块链,看不清的ICO人心【转】

    比特币又开始下跌了,是狂欢尽头还是又一波调整,无从得知,背后的乱象会让监管者继续心烦,而这乱象对我来说,有时候会有些心寒. 你说我怎么可能想到,我一个写程序的人,突然有一天会发现,朋友圈里有一些搞技术 ...

  10. [ CodeVS冲杯之路 ] P1039

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1039/ 一道赤裸裸的嘲讽型数学题,推出来的话算法代码就3行,没有推出来连暴力都无从入手…… 设 f(n,m) 为整数 ...