首页 > 代码库 > Codevs 2796 最小完全图
Codevs 2796 最小完全图
2796 最小完全图
http://codevs.cn/problem/2796/
题目描述 Description
若一个图的每一对不同顶点都恰有一条边相连,则称为完全图。
最小生成树MST在Smart的指引下找到了你,希望你能帮它变成一个最小完全图(边权之和最小的完全图)。
注意:必须保证这个最小生成树MST对于最后求出的最小完全图是唯一的。
输入描述 Input Description
第一行一个整数n,表示生成树的节点数。
接下来有n-1行,每行有三个正整数,依次表示每条边的顶点编号和边权。
(顶点的边号在1-n之间,边权<231)
输出描述 Output Description
一个整数ans,表示以该树为最小生成树的最小完全图的边权之和。
样例输入 Sample Input
4
1 2 1
1 3 1
1 4 2
样例输出 Sample Output
12
数据范围及提示 Data Size & Hint
30%的数据:n<1000;
100%的数据:n≤20000,所有的边权<2^31。
/*树就是不存在环的图,而完全图就要求我们把树上的点间关系全部变成环 首先把各边从小到大排序,以保证从小的开始,结果更优 以树上的每条边为基底,进行合并比如用到边i,其端点为a,b将b所在的树合并到a所在的树上,也就是要求两棵小树中所有的点构成一个小的完全图 那么从b树上所有点都向a图上所有点连一条长为v[i]+1的线即可,这样的线一共有siz[a]*siz[b]-1条 上式中"-1"代表的那条边就是边i,其边权为v[i] 就这样跑完最小生成树的所有边,同时将边权累加即可 最后提醒 所有的边权<2^31,别忘了用long long */#include<iostream>#include<cstdio>#include<algorithm>using namespace std;long long siz[20010],n,ans,father[20010];struct node{ long long from,to,v;}e[20010];long long find(long long a){ if(father[a]==a)return father[a]; else return father[a]=find(father[a]);}long long cmp(node a,node b){ return a.v<b.v;}int main(){ scanf("%d",&n); for(long long i=1;i<n;i++)scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].v); for(long long i=1;i<=n;i++)father[i]=i,siz[i]=1; sort(e+1,e+n,cmp); for(long long i=1;i<n;i++){ long long a=e[i].from,b=e[i].to; long long f1=find(a),f2=find(b); father[f2]=f1; ans+=e[i].v; long long value=http://www.mamicode.com/siz[f1]*siz[f2]-1; ans+=value*(e[i].v+1); siz[f1]+=siz[f2];//与19行对应,注意是谁变成了谁的子树 } cout<<ans;}
Codevs 2796 最小完全图
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。