题目 2398:
信息学奥赛一本通T1489-构造完全图
时间限制: 2s 内存限制: 192MB 提交: 16 解决: 9
题目描述
对于完全图 G,若有且仅有一棵最小生成树为 T,则称完全图 G 是树 T 扩展出的。
给你一棵树 T,找出 T 能扩展出的边权和最小的完全图 G。
输入格式
第一行 N 表示树 T 的点数;
接下来 N−1 行三个整数 Si,Ti,Di ;描述一条边(Si,Ti)权值为 Di ;
保证输入数据构成一棵树。
输出格式
输出仅一个数,表示最小的完全图 G 的边权和。
样例输入
复制
4 1 2 1 1 3 1 1 4 2样例输出
复制
12提示
样例说明
添加 D(2,3)=2,D(3,4)=3,D(2,4)=3 即可。
数据范围:
对于 20% 的数据,N≤10;
对于 50% 的数据,N≤1000;
对于 100% 的数据,N≤105,1≤Di≤105 。
思路:类似于kruskal建树过程,先找到最小树边,再在此基础上加边,使其成为一个局部完全图。依次进行,最后就得到一个最小权完全图。注意加边时边权应该为最小树边权加1,否则就不满足最小生成树的唯一性。
cpp#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int p[N]; int cnt[N]; long long ans; struct edge{ int a,b,w; bool operator<(edge&W){ return w<W.w; } }e[N]; int t; int find(int x){ if(x!=p[x]){ p[x]=find(p[x]); } return p[x]; } int main() { cin>>t; for(int i=1;i<=t;i++){ p[i]=i; cnt[i]=1; } for(int i=1;i<t;i++){ int a,b,c; cin>>a>>b>>c; e[i].a=a,e[i].b=b,e[i].w=c; } sort(e+1,e+t); for(int i=1;i<t;i++){ int a=e[i].a; int b=e[i].b; int c=e[i].w; int x=find(a); int y=find(b); if(x!=y){ p[x]=y; ans+=(long long)(cnt[x]*cnt[y]-1)*(c+1); cnt[y]=cnt[x]+cnt[y]; ans+=c; } } cout<<ans; }
图论之构造完全图
Romanticroom2024-11-19 9:09
相关推荐
2401_876221341 分钟前
因数个数、因数和、因数积云里雾里!11 分钟前
LeetCode 744. 寻找比目标字母大的最小字母 | 从低效到最优的二分解法优化一条大祥脚26 分钟前
26.1.3 快速幂+容斥 树上dp+快速幂 带前缀和的快速幂 正序转倒序 子序列自动机 线段树维护滑窗二狗哈30 分钟前
czsc入门5: Tick RawBar(原始k线) NewBar (新K线)Tisfy35 分钟前
LeetCode 0865.具有所有最深节点的最小子树:深度优先搜索(一次DFS + Python5行)Q741_14740 分钟前
C++ 队列 宽度优先搜索 BFS 力扣 429. N 叉树的层序遍历 C++ 每日一题Yzzz-F41 分钟前
P4145 上帝造题的七分钟 2 / 花神游历各国[线段树 区间开方(剪枝) + 区间求和]Zzz不能停43 分钟前
堆排序算法及大小堆区别zd8451015001 小时前
stm32f407 电机多轴联动算法代码游侠1 小时前
应用——Linux FrameBuffer图形显示与多线程消息系统项目