AcWing 346. 走廊泼水节
2021/5/4 18:27:27
本文主要是介绍AcWing 346. 走廊泼水节,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
原题链接
考察:最小生成树
思路:
本题要求完成图的最小生成树依旧是原树.考虑Kruskal算法,每次都是选择当前边两端合并为一个集合,我们要保证为完全图的话需要让左右端点的集合两两之间连一条边,同时保证原树的边是当前集合最小的边.因为原边不能代替所以考虑取road[i].w+1的边,边的数量是左端点集合数*右端点集合数-1.
每次合并集合都构造完全图,这样合并完成后一定是完全图.
按照上面求ans的话,如果边从大到小枚举会使得答案更小,但是这样的答案是不合法的,这样会使完成图的最小生成树比原树更小.
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 6010; 6 int p[N],n,sz[N]; 7 struct Road{ 8 int u,v,w; 9 bool operator<(const Road& r)const{ 10 return this->w<r.w; 11 } 12 }road[N]; 13 int findf(int x) 14 { 15 if(x!=p[x]) p[x] = findf(p[x]); 16 return p[x]; 17 } 18 int main() 19 { 20 int T; 21 scanf("%d",&T); 22 while(T--) 23 { 24 scanf("%d",&n); 25 for(int i=1;i<=n;i++) p[i] = i,sz[i] = 1; 26 for(int i=1;i<n;i++) 27 { 28 int a,b,w; scanf("%d%d%d",&a,&b,&w); 29 road[i] = {a,b,w}; 30 } 31 sort(road+1,road+n); 32 int sum = 0; 33 for(int i=1;i<n;i++) 34 { 35 int pa = findf(road[i].u),pb = findf(road[i].v); 36 if(pa==pb) continue; 37 sum += (sz[pb]*sz[pa]-1)*(road[i].w+1); 38 sz[pb]+=sz[pa]; 39 p[pa] = pb; 40 } 41 printf("%d\n",sum); 42 } 43 return 0; 44 }
这篇关于AcWing 346. 走廊泼水节的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享