码迷,mamicode.com
首页 > 其他好文 > 详细

边权最大差最小的生成树

时间:2018-08-01 18:18:47      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:http   ret   无法   技术分享   现在   维护   png   get   更新   

技术分享图片

 

       最小生成树十分简单,想求最大边权最小的一个数。我们利用树的性质和单调性,维护所有节点的父节点(刚开始的时候弄成自己)和一个当前用于建树的边数sum。先sort把所有边按边权从小到大排序,然后向后遍历,如果这条边的两端点最大的父亲不一样就令他们合并,并且sum++。当sum==n-1时停下来,答案就是此时的边权。

       现在要求边权最大差最小的生成树,对小数据版就可以随便搞:先跑一遍最小生成树,如果停下来时sum!=n-1说明用所有的边也无法使n个点在同一个树上,输出-1。如果等于了n-1,那么此时的边权减最小的边权是一个可行解。再从小到大枚举最小边,以第i个边为最小边到达第f条边sum==n-1停下来,更新答案,ans=min(ans,o[f].v-o[i].v);如果到最后也无法构造出树就可以return 0了。

      然而这是小数据,大数据肯定支持不了。

  我发现改变最小边时中间无数的边被拆下来又接回去,浪费了大量时间。

  于是就觉得可以维护一个数组bian[],跑第一次时把经过的每个边的两端点的bian[]++,最后sum=n-1时停下来,此时的bian[j]表示从第一条边到第i条边的边权范围中所有边都连上的情况下j点所连边的数量。

  也就是说,即使get(x)==get(y)也要把bian[x]++,bian[y]++;因为一会删边的时候可以直接判断该端点要不要删掉。

  然后左端点是1,右端点是i,先把左端点向左走,也就是最小边向大的方向移动,并且把自己的两端点bian[]--,有1个变为0时就sum--,两个变为0还是sum--。一旦减了就不管左端点了,开始将右端点向右移动,还是把自己的端点bian[]++,如果发现了父节点不一样的就连起来,sum++。知道sum==n-1,停下来,更新答案。

  然后再将左端点向右走,直到sum又被减了,再把右端点向右走,直到sum再加回去,更新答案,一直循环……

  直到直到右端点到达了m且sum!=n-1了的时候break。如果右端点到达m还要回去看看左端点能不能再向右走而且sum不被减。

  嗯也可以在左端点向右走而且sum不被减时更新答案,反正我写了两天也没弄出来。

  交给你了,李泽铎!打破通过一的惨案的光荣任务在你身上

边权最大差最小的生成树

标签:http   ret   无法   技术分享   现在   维护   png   get   更新   

原文地址:https://www.cnblogs.com/qywyt/p/9402471.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!