题解 | #构造完全图#

黑暗城堡

https://ac.nowcoder.com/acm/contest/958/A

构造完全图

题意:

给你一棵树,将这棵树扩充为完全图,满足该图的最小生成树为这棵树。求边权和值最小是多少。

思路:

根据完全图的性质,每两个点都至少有一条边联通。再想 KruskalKruskal 算法的实现流程,我们只需要在合并两个单独并查集的时候,记录一下贡献就可以了。因为在 KruskalKruskal 合并两个并查集的时候只是保留了一条边权最小的边使两个单独的联通块 ZZYY 联通。所以如要构成完全图,根据乘法原理,每次操作的贡献就为 SZSY1\large S_Z * S_Y - 1 S\large S 为联通块中节点的个数,减去的是已经被加入 MSTMST 中的树边。由于要满足扩充后的完全图的 MSTMST 仍然为这棵树, 那么加入的非树边的权值需要严格大于树边(如果小于就会被加入 MSTMST 中使原树结构被改变),同时又要满足 增加边的权值最小 所以这里每次合并的贡献就为 (SZSY1)(w+1)\large (S_Z * S_Y - 1 ) * (w + 1)ww 为树边的权值。

code

#include <bits/stdc++.h>
#define int long long 
const int maxn = 2e5 + 7 ;
using namespace std ;
struct node 
{
    int frm , to , nxt , dis ;
} ed[maxn] ;
bool operator < (node x , node y)
{
	return x.dis < y.dis ;
}
int n , m , cnt , tot , ans , t  ;
int head[maxn] , fa[maxn] , s[maxn] ;
int find(int x)
{
	if(x == fa[x])	return x ;
	return fa[x] = find(fa[x]) ;
} 
void add(int u , int v , int w)
{
    ed[++cnt] = { u , v , head[u] , w } ;
    head[u] = cnt ;
}
signed main()
{
        cin >> n ;  cnt = 0 , tot = 0 , ans = 0 ;   
 		for(int i = 0 ; i <= 2*n ; i++ )	fa[i] = i , s[i] = 1 ; 
        for(int i = 1 ; i < n ; i++ )
        {
            int u , v , w ;     cin >> u >> v >> w ; 
            add(u , v , w) ;    add(v , u , w) ;
            ans += w ;
        }
        sort(ed + 1 , ed + 2*n + 1) ; 
        for(int i = 1 ; i <= 2*n ; i++ )
        {
            int u = find(ed[i].frm) , v = find(ed[i].to) ;
            if(u == v)  continue ;
            ans += (ed[i].dis + 1) * (s[u] * s[v] - 1) ;
            fa[v] = u ; s[u] += s[v] ;  tot++ ;
        //cout << "suz_ak_ioi" << s[v]  ;
            if(tot == n)    break ;
        }
        cout << ans << '\n' ;
    return 0 ; 
}

全部评论

相关推荐

二月份来北京实习,虽然提前做了攻略,但是是人生第一次经历租房,全程自己搞定,所以难免还是踩坑了😅奉劝大家,租房不要只看自己的房间如何,还要看别人的房门口环境如何因为我就是那个倒霉蛋,我旁边房间额门口堆了一大堆杂物,都是另一个房间的人放在外面的,而且他门口放了几十双鞋子,冬天还好,现在是夏天,可太味了,怎么有这么多鞋啊啊啊啊,请看图片O(≧口≦)O一开始这屋里是一个人住,后来变成两个人住(他说他妈妈来北京看病暂时住,ok能体谅的)但是大概一个多月以后他妈妈回家了,无缝衔接了一位女朋友接着住,而且他的女朋友巨能买东西,我真的不得不吐槽,🥲我不管别人怎么花钱的,但是你买东西你起不来,你能不能换个时间约送上门,总是在周内或者周末的某一天早上七点多,没到起来的时间,快递员框框敲门了!!!!而且经常点外卖但是我们楼下有门禁,外卖员按响铃他俩不去解锁,一直等一直等,等到我们其他人受不了去帮解锁,吵得要死,他们像聋了一样!!!服啦!!!我的房租一个月不到1600,但是是阳隔,很不隔音,隔壁的大哥有时候会半夜吃薯片或者嗑瓜子(凌晨两三点的时候)好几次我都从梦里被嗑出来了🥲还好还剩两个月就实习结束可以回家了,呜呜想家,想我自己的窝😭
码农索隆:这也是我不喜欢合租的原因
我的租房踩坑经历
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务