LuoguP2700逐个击破【并查集/生成树/正难则反】By cellur925
题目传送门
题目大意:给你一棵树,求把其中k个点相互隔离(不连通)所需要的边权代价。
这题我开始是想要求出把k个点联通的最小代价的,但后来发现还是实现起来比较困难,题解里貌似也没有这种做法,于是就鸽了。但是大体的思考方向还是不直接去想把k个点隔离,而是把问题转化。
花费最小代价删边->花费最大代价建边。而建边的时候如果遇到一条两边都是敌人的边,我们显然是不需要建的,所以这其实我们需要维护敌人的网络,用并查集来维护。
首先我们标记敌人点,再把边从大到小排序。枚举所有的边,如果它两端点都是敌人,那肯定不连他。如果两端点有一个是敌人,也连上,并在那个无辜的点上打一个标记,因为之后的点也不能再连他。于是我们就可以用并查集维护。最后注意我们之后调用的都是这个集合的代表元,即getf。
Code
1 #include<cstdio> 2 #include<algorithm> 3 #define maxn 100090 4 5 using namespace std; 6 typedef long long ll; 7 8 int n,k; 9 ll ans; 10 int vis[maxn],fa[maxn]; 11 struct node{ 12 int to,from,val; 13 }edge[maxn*2]; 14 15 bool cmp(node a,node b) 16 { 17 return a.val>b.val; 18 } 19 20 int getf(int x) 21 { 22 if(fa[x]==x) return x; 23 return getf(fa[x]); 24 } 25 26 int main() 27 { 28 scanf("%d%d",&n,&k); 29 for(int i=1;i<=k;i++) 30 { 31 int x=0; 32 scanf("%d",&x); 33 vis[x]=1; 34 } 35 for(int i=1;i<=n-1;i++) 36 scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val),ans+=edge[i].val; 37 for(int i=1;i<=n;i++) fa[i]=i; 38 sort(edge+1,edge+1+n-1,cmp); 39 for(int i=1;i<=n-1;i++) 40 { 41 int pp=getf(edge[i].from),qq=getf(edge[i].to); 42 if(vis[pp]&&vis[qq]) continue; 43 ans-=edge[i].val; 44 if(qq!=pp) fa[qq]=pp; 45 if(vis[pp]) vis[qq]=1; 46 else if(vis[qq]) vis[pp]=1; 47 } 48 printf("%lld",ans); 49 return 0; 50 }
View Code
转载于:https://www.cnblogs.com/nopartyfoucaodong/p/9744089.html
LuoguP2700逐个击破【并查集/生成树/正难则反】By cellur925相关推荐
- P2700 逐个击破 并查集/生成树
P2700 逐个击破 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 也就是让k个节点互不连通,很容易知道要产生这种情况,就必须将原图划分为k个互相独立的联通块,且每个联通块有且仅有 ...
- 洛谷题目--P1008三连击--正难则反、模拟、枚举、暴力<每日一题>
题目链接 P1008 [NOIP1998 普及组] 三连击 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1008 ...
- [2016ACM多校] HDU5784 极角序 正难则反
题意 给N个点,问组成多少个锐角三角形.N<=2000 思路 一开始想的是枚举线段,然后构成锐角三角形的另一个点在线段两端点的垂线内,还在以线段为直径的圆外.垂线好搞,圆卡到比赛结束.赛后发现直 ...
- 51nod 1050 循环数组最大子段和【环形DP/最大子段和/正难则反】
1050 循环数组最大子段和 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 N个整数组成的循环序列a[1],a[2],a[3],-,a[n],求该 ...
- CodeForces - 1445E Team-Building(可撤销并查集)
题目链接:点击查看 题目大意:给出一张有 n 个点和 m 条边的图,每个点都有一个种类,共有 k 个种类,现在要从 k 个种类中每次选出两种,对所有 C( k , 2 ) 种组合单独讨论,对于选出的两 ...
- HDU多校2 - 6763 Total Eclipse(贪心+并查集)
题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在每个点都有一个点权,对于每次操作,可以选择一个点以及其周围能够连接的所有点,令其点权减一,当某个点的点权减到 0 时,就相 ...
- HDU - 5176 The Experience of Love(并查集)
题目链接:点击查看 题目大意:给出一棵边权树,现在要求任意两点之间:最大权值的边减去最小权值的边之和 题目分析:第一步可以先将公式转换一下:,这样问题就转换为了如何求任意两点之间的最大(最小)权值之和 ...
- 中石油训练赛 - 奎奎画画(思维+并查集+离线处理)
题目描述 "为你写诗,为你静止,为你做不可能的事",爱情是一种怪事,它让奎奎开始学习画画.奎奎认为一张画的艺术价值等于画上的白色联通块个数(当一个格子和它上下左右四个方向上的某个相 ...
- CodeForces - 722C Destroying Array(倒着并查集+离线处理)
题目链接:点击查看 题目大意:给出一个数列a,现在给出操作b,每次操作都会删除掉数列a中指定位置的数,问每次删除后,最大连续字段和是多少 题目分析:一开始看到最大连续字段和,以为是要用dp,又看了一下 ...
- 【转】并查集MST题集
转自:http://blog.csdn.net/shahdza/article/details/7779230 [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 ...
最新文章
- oracle-闪回技术2
- 01.几张图轻松理解String.intern()
- 在 Windows 中,当一个应用程序窗口被关闭,该应用程序将会保留在哪里?
- 数组实例的fill()方法 fill()方法
- Codeforces Round #456 (Div. 2): E. Prime Gift(折半枚举)
- 取rtsp流数据_SDP在RTSP、国标GB28181、WebRTC中的实践
- python123.io能不能补交作业_作业分配问题-回溯法-Python3
- 从零开始学习前端JAVASCRIPT — 14、闭包与继承
- 团队编程项目作业4-开发文档
- flowchart流程图编程语言下载_c语言流程图生成器下载
- iScroll实现下拉刷新和上滑加载更多
- echarts 正负条形图
- IPv6系列-彻底弄明白有状态与无状态配置IPv6地址
- 51单片机常用波特率初值表(11.0592M和12M)
- 虚拟机安装windows10
- 关于内部用户通过easy-ip访问外网
- 计算机应用技术未来职业规划书,计算机应用技术专业大学生职业生涯规划书
- 电容器的基础知识(2)
- python爬虫网易云音乐最热评论并分析_python爬虫入门 实战(三)---爬网易云音乐热门评论...
- Java基础三个排序详解_继承粗解语法关键字分析