TM终于过了。。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define maxv 300500
  6. #define maxe 800500
  7. #define inf 0x7fffffffffffffff
  8. using namespace std;
  9. struct edge
  10. {
  11. long long v,w,nxt;
  12. }e[maxe];
  13. struct edge_mp
  14. {
  15. long long u,v,w,flag;
  16. }mp[maxe];
  17. long long n,m,g[maxv],nume=,father[maxv],anc[maxv][],mx1[maxv][],mx2[maxv][],ans=,dx=inf,dis[maxv];
  18. long long r1=,r2=;
  19. bool cmp(edge_mp x,edge_mp y)
  20. {
  21. return x.w<y.w;
  22. }
  23. void addedge(long long u,long long v,long long w)
  24. {
  25. e[++nume].v=v;
  26. e[nume].w=w;
  27. e[nume].nxt=g[u];
  28. g[u]=nume;
  29. }
  30. long long getfather(long long x)
  31. {
  32. if (father[x]!=x)
  33. father[x]=getfather(father[x]);
  34. return father[x];
  35. }
  36. void kruskal()
  37. {
  38. for (long long i=;i<=n;i++) father[i]=i;
  39. sort(mp+,mp+m+,cmp);
  40. for (long long i=;i<=m;i++)
  41. {
  42. long long u=mp[i].u,v=mp[i].v,w=mp[i].w;
  43. if (getfather(u)!=getfather(v))
  44. {
  45. father[getfather(u)]=getfather(v);mp[i].flag=;ans+=w;
  46. addedge(u,v,w);addedge(v,u,w);
  47. }
  48. }
  49. }
  50. void dfs(long long x,long long father)
  51. {
  52. for (long long i=g[x];i;i=e[i].nxt)
  53. {
  54. long long v=e[i].v;
  55. if (v!=father)
  56. {
  57. anc[v][]=x;mx1[v][]=e[i].w;mx2[v][]=;
  58. dis[v]=dis[x]+;
  59. dfs(v,x);
  60. }
  61. }
  62. }
  63. void get_table()
  64. {
  65. for (long long e=;e<=;e++)
  66. for (long long i=;i<=n;i++)
  67. {
  68. anc[i][e]=anc[anc[i][e-]][e-];
  69. long long regis[];
  70. regis[]=mx1[i][e-];regis[]=mx1[anc[i][e-]][e-];
  71. regis[]=mx2[i][e-];regis[]=mx2[anc[i][e-]][e-];
  72. sort(regis+,regis+);
  73. mx1[i][e]=regis[];
  74. for (long long j=;j>=;j--)
  75. {
  76. if (regis[j]==regis[j+]) continue;
  77. else {mx2[i][e]=regis[j];break;}
  78. }
  79. }
  80. }
  81.  
  82. void get_ans(long long x)
  83. {
  84. long long u=mp[x].u,v=mp[x].v;r1=-;r2=-;
  85. long long k1=-,k2=-,k3=-,k4=-;
  86. if (dis[u]<dis[v]) swap(u,v);
  87. if (dis[u]!=dis[v])
  88. {
  89. for (long long e=;e>=;e--)
  90. {
  91. long long pos=anc[u][e];
  92. if ((dis[pos]>=dis[v]) && (pos>))
  93. {
  94. long long regis[];
  95. regis[]=mx1[u][e];regis[]=mx2[u][e];regis[]=k1;regis[]=k2;
  96. sort(regis+,regis+);
  97. k1=regis[];
  98. for (long long i=;i>=;i--)
  99. {
  100. if (regis[i]==regis[i+]) continue;
  101. else {k2=regis[i];break;}
  102. }
  103. u=pos;
  104. }
  105. }
  106. }
  107. if (u==v)
  108. {
  109. r1=k1;r2=k2;
  110. return;
  111. }
  112. for (long long e=;e>=;e--)
  113. {
  114. long long posu=anc[u][e],posv=anc[v][e];
  115. if (posu!=posv)
  116. {
  117. long long regis[];
  118. regis[]=mx1[u][e];regis[]=mx2[u][e];regis[]=k1;regis[]=k2;
  119. sort(regis+,regis+);
  120. k1=regis[];
  121. for (long long i=;i>=;i--)
  122. {
  123. if (regis[i]==regis[i+]) continue;
  124. else {k2=regis[i];break;}
  125. }
  126. regis[]=mx1[v][e];regis[]=mx2[v][e];regis[]=k3;regis[]=k4;
  127. sort(regis+,regis+);
  128. k3=regis[];
  129. for (long long i=;i>=;i--)
  130. {
  131. if (regis[i]==regis[i+]) continue;
  132. else {k4=regis[i];break;}
  133. }
  134. u=posu;v=posv;
  135. }
  136. }
  137. long long regis[];
  138. regis[]=k1;regis[]=k2;regis[]=k3;regis[]=k4;regis[]=mx1[u][];regis[]=mx1[v][];
  139. sort(regis+,regis+);
  140. r1=regis[];
  141. for (long long i=;i>=;i--)
  142. {
  143. if (regis[i]==regis[i+]) continue;
  144. else {r2=regis[i];break;}
  145. }
  146. }
  147. int main()
  148. {
  149. scanf("%lld%lld",&n,&m);
  150. for (long long i=;i<=m;i++)
  151. {
  152. scanf("%lld%lld%lld",&mp[i].u,&mp[i].v,&mp[i].w);
  153. mp[i].flag=;
  154. }
  155. kruskal();
  156. memset(mx1,,sizeof(mx1));
  157. memset(mx2,,sizeof(mx2));
  158. dfs(,);
  159. get_table();
  160. for (long long i=;i<=m;i++)
  161. {
  162. if (mp[i].flag) continue;
  163. long long u=mp[i].u,v=mp[i].v,w=mp[i].w;
  164. get_ans(i);
  165. if (r1==mp[i].w)
  166. {
  167. if (r2==-) continue;
  168. dx=min(dx,mp[i].w-r2);
  169. }
  170. else if (r1<mp[i].w) dx=min(dx,mp[i].w-r1);
  171. }
  172. printf("%lld\n",ans+dx);
  173. return ;
  174. }

BZOJ 1977 次小生成树的更多相关文章

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

    话说这个[BeiJing2010组队]是个什喵玩意? 这是一道严格次小生成树,而次小生成树的做法是层出不穷的 MATO IS NO.1 的博客里对两种算法都有很好的解释,值得拥有:  (果然除我以外, ...

  2. BZOJ 1977 次小生成树(最近公共祖先)

    题意:求一棵树的严格次小生成树,即权值严格大于最小生成树且权值最小的生成树. 先求最小生成树,对于每个不在树中的边,取两点间路径的信息,如果这条边的权值等于路径中的权值最大值,那就删掉路径中的次大值, ...

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

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

  4. BZOJ 1977 严格次小生成树(算竞进阶习题)

    树上倍增+kruskal 要找严格次小生成树,肯定先要找到最小生成树. 我们先把最小生成树的边找出来建树,然后依次枚举非树边,容易想到一种方式: 对于每条非树边(u,v),他会与树上的两个点构成环,我 ...

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

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

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

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

  7. BZOJ 1977 严格次小生成树

    小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小 ...

  8. bzoj 1977 洛谷P4180 严格次小生成树

    Description: 给定一张N个节点M条边的无向图,求该图的严格次小生成树.设最小生成树边权之和为sum,那么严格次小生成树就是边权之和大于sum的最小的一个 Input: 第一行包含两个整数N ...

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

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

随机推荐

  1. vc++ 获取当前用户名

    #include<afxwin.h> #include <stdio.h> int main(void) { char userName[MAX_PATH]; unsigned ...

  2. Codeforces446C DZY Loves Fibonacci Numbers(线段树 or 分块?)

    第一次看到段更斐波那契数列的,整个人都不会好了.事后看了题解才明白了一些. 首先利用二次剩余的知识,以及一些数列递推式子有下面的 至于怎么解出x^2==5(mod 10^9+9),我就不知道了,但是要 ...

  3. java 反射创建对象并传入参数

    /* * 通过反射创建带参数的对象 */ public Object Creatobject(String ClassPath, Object[] Params) throws Exception { ...

  4. lintcode:组成最大的数

    最大数 给出一组非负整数,重新排列他们的顺序把他们组成一个最大的整数. 注意事项 最后的结果可能很大,所以我们返回一个字符串来代替这个整数. 样例 给出 [1, 20, 23, 4, 8],返回组合最 ...

  5. run fsck manually

    就出现unexpected inconsistency run fsck manually这个问题了. 磁盘出问题,需要用 Fsck修复... 解决方案: 在命令行输入#mount | grep ”o ...

  6. 一些时间的概念与区分(UTC、GMT、LT、TAI等)

    UT - 世界时 Universal Time世界时是最早的时间标准.在1884年,国际上将1s确定为全年内每日平均长度的1/8.64×104.以此标准形成的时间系统,称为世界时,即 UT1.1972 ...

  7. Haproxy均衡负载部署和配置文件详解

    HAproxy均衡负载部署和配置文件详解 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G ...

  8. iOS 开发--添加工程

    文/Bison(简书作者)原文链接:http://www.jianshu.com/p/dd71e15df5d0著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 第一部分,配置项目 在此只 ...

  9. 【重走Android之路】【番外篇】关于==和equals

    [重走Android之路][番外篇]关于==和equals   在实际的编程当中,经常会使用==和equals来判断变量是否相同.但是这两种比较方式也常常让人搞得云里雾里摸不着头脑.下面是我个人做的总 ...

  10. JVM垃圾回收机制总结(1) :一些概念

    数据类型 Java虚拟机中,数据类型可以分为两类:基本类型 和引用类型 .基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本 ...