博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【NOIP校内模拟】T2 华莱士(环套树)
阅读量:4637 次
发布时间:2019-06-09

本文共 1301 字,大约阅读时间需要 4 分钟。

其实就是要求最小的环套树森林

我们现在只考虑如何合并 设当前边的两个端点是x,y

若x,y在一个联通块里

那这个联通块要么是树 要么是环套树

假如是个环套树 加一条边后必定变成两个环 不符合要求

假如是个树 加一条边就变成了换套树 符合要求

若x,y不在一个联通块里

假如同为环套树 加一条边后必定变成两个环 不符合要求

假如同为树 加一条边后还是树 符合要求
假如一棵树 一棵环套树 加了过后变成环套树 符合要求

然后类似kruskal就好了

#include
#define N 500005#define int long long using namespace std;struct data{ int x,y,z;}edge[2*N];int father[N];int n,m,tot,type[N]; //type=0 树 type=1 环 inline bool cmp(const data &a,const data &b){ return a.z
>n>>m; for(int i=1;i<=n;i++) father[i]=i; for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addedge(x,y,z); } sort(edge+1,edge+tot+1,cmp); int ans=0,cnt=0; for(int i=1;i<=m;i++) { int fx=getfather(edge[i].x),fy=getfather(edge[i].y); if(fx==fy) //在一个联通块 { if(type[fx]==0)//是个树 { type[fx]=1; //他将变成环套树 ans+=edge[i].z; ++cnt; } //环肯定是不能再加边的 } else { if(type[fx]&&type[fy]) continue; //两个环 father[fx]=fy; type[fy]=type[fy]|type[fx]; ans+=edge[i].z; ++cnt; } } if(cnt!=n) puts("No"); else cout<

转载于:https://www.cnblogs.com/Patrickpwq/articles/9798702.html

你可能感兴趣的文章
mfc Radio Buttons
查看>>
Python【第三章】:python 面向对象 (new)
查看>>
redis学习总结
查看>>
css文字禁止选中
查看>>
[刘阳Java]_Java环境搭建_第2讲
查看>>
[JavaScript]父子窗口间参数传递
查看>>
Test Controller Tool
查看>>
86. Partition List
查看>>
[LintCode] 378 Convert Binary Search Tree to Doubly Linked List 解题报告
查看>>
JAVA-初步认识-常用对象API(集合框架-泛型-泛型限定-上限的体现)
查看>>
caffe中的若干问题
查看>>
webpack学习(一)—— 入门
查看>>
c# 调用 webservices (转载)
查看>>
结对-(first)
查看>>
P1567 统计天数
查看>>
NOIp2018集训test-10-6/test-10-7 (联考五day1/day2)
查看>>
C++练习 | 运算符重载练习
查看>>
dalvik
查看>>
[总结] 第一类斯特林数
查看>>
PCI PCI-X PCI-E介绍
查看>>