51nod1307(暴力树剖/二分dfs/并查集)
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307
题意: 中文题诶~
思路:
解法1:暴力树剖
用一个数组 num[i] 维护编号为 i 的边当前最大能承受的重量. 在加边的过程中根据给出的父亲节点将当前边所在的链上所有边的num都减去当前加的边的重量, 注意当前边也要减自重. 那么当num首次出现负数时加的边号即位答案;
事实上这个算法的时间复杂度是O(n^2)的, 不过本题并没有出那种退化成单链的数据, 所以直接暴力也能水过;
代码:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 const int MAXN = 5e4 + 10; 6 struct node{ 7 int c, w, pre; 8 }gel[MAXN]; 9 int num[MAXN];//num[i]为编号为i的绳子当前可以承受的最大重量 10 11 int main(void){ 12 int n, ans = -1; 13 scanf("%d", &n); 14 for(int i = 0; i < n; i++){ 15 scanf("%d%d%d", &gel[i].c, &gel[i].w, &gel[i].pre); 16 if(ans != -1) continue; 17 num[i] = gel[i].c; 18 int cnt = i; 19 while(cnt != -1){ 20 num[cnt] -= gel[i].w; 21 if(ans == -1 && num[cnt] <= -1) ans = i; 22 cnt = gel[cnt].pre;//指向cnt的父亲节点 23 } 24 } 25 if(ans == -1) cout << n << endl; 26 else cout << ans << endl; 27 return 0; 28 }
View Code
解法2: 二分 + dfs
很显然在加边的过程中所有边的承受重量都是单调不减的, 那么可以考虑二分答案. 不过要注意判断函数的写法, 每一次判断都需要判断当前 mid条 边组成的树的所有边, 而不能只判断当前 mid 所在链上的边, 显然其他链上也可能存在不合法的边. 判断所有边的话可以 dfs 一遍, 回溯时判断即可.
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <vector> 4 #define ll long long 5 using namespace std; 6 7 const int MAXN = 5e4 + 10; 8 struct node{ 9 int c, w, pre; 10 }gel[MAXN]; 11 vector<int> sol[MAXN]; 12 bool flag; 13 14 ll dfs(int u, int x){ 15 ll sum = gel[u].w; 16 if(u > x) return 0;//mid边后面的不要算上去 17 for(int i = 0; i < sol[u].size(); i++){ 18 sum += dfs(sol[u][i], x); 19 } 20 if(sum > gel[u].c && u) flag = false;//0是一个虚根,并没有对应的边 21 return sum; 22 } 23 24 int main(void){ 25 int n; 26 scanf("%d", &n); 27 for(int i = 1; i <= n; i++){ 28 scanf("%d%d%d", &gel[i].c, &gel[i].w, &gel[i].pre); 29 gel[i].pre++; 30 sol[gel[i].pre].push_back(i); 31 } 32 int l = 1, r = n, cnt = n; 33 while(l <= r){ 34 flag = true; 35 int mid = (l + r) >> 1; 36 dfs(0, mid); 37 if(flag) cnt = mid, l = mid + 1; 38 else r = mid - 1; 39 } 40 printf("%d\n", cnt); 41 }
View Code
解法3: 并查集
1 #include <iostream> 2 #include <stdio.h> 3 #include <vector> 4 #define ll long long 5 using namespace std; 6 7 const int MAXN = 1e5 + 10; 8 struct node{ 9 ll c, w, p; 10 }gel[MAXN]; 11 12 ll ww[MAXN]; 13 vector<int> vt[MAXN]; 14 int pre[MAXN], sol; 15 16 int find(int x){ 17 return pre[x] == x ? x : pre[x] = find(pre[x]); 18 } 19 20 void update(int u){ 21 for(int i = 0; i < vt[u].size(); i++){ 22 gel[u].w += gel[vt[u][i]].w; 23 pre[vt[u][i]] = u; 24 } 25 while(gel[u].w > gel[u].c){//u即为当前根节点 26 gel[find(sol)].w -= ww[sol]; 27 sol--; 28 } 29 } 30 31 int main(void){ 32 int n; 33 scanf("%d", &n); 34 for(int i = 1; i <= n; i++){ 35 scanf("%lld%lld%lld", &gel[i].c, &gel[i].w, &gel[i].p); 36 gel[i].p++; 37 vt[gel[i].p].push_back(i); 38 ww[i] = gel[i].w;//后面会对gel操作,所以需要先记录下gel的初始值来 39 pre[i] = i; 40 } 41 sol = n; 42 for(int i = n; i > 0; i--){ 43 update(i); 44 } 45 printf("%d\n", sol); 46 return 0; 47 }
View Code
转载于:https://www.cnblogs.com/geloutingyu/p/7121750.html
51nod1307(暴力树剖/二分dfs/并查集)相关推荐
- 51nod 1307 绳子与重物 二分+dfs / 并查集
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307 题意: 题解: 方法一: 因为所有绳子最终组成了1棵树 ...
- 数据结构之树的应用:并查集
树的应用:并查集 并查集的概念: 三种基本操作: 例: 代码实现: 并查集的概念: 将所有的数据元素放在一个集合中,将集合分成若干个互不相交的子集,每一个子集对应一颗树,所有的自己组成森林. 三种基本 ...
- PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度
文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...
- XXI Open Cup. Grand Prix of Korea I. Query On A Tree 17 树剖 + 二分 + 树带权重心
传送门 文章目录 题意: 思路: 题意: 给你一棵树,每棵树初始权值都为000,现在给你两个操作: (1)(1)(1)将uuu的子树权值全部加111. (2)(2)(2)将(u,v)(u,v)(u,v ...
- 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)
题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...
- BZOJ 2143 飞飞侠(线段树优化建边 / 并查集优化最短路)【BZOJ修复工程】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2143 是 hydro 的 BZOJ ...
- 【CF813F】Bipartite Checking(线段树分治+可删除并查集)
文章目录 title solution code title You are given an undirected graph consisting of n vertices. Initially ...
- Codeforces Round #548 (Div. 2) C. Edgy Trees(dfs || 并查集)
题目链接:https://codeforces.com/contest/1139/problem/C 题意:给了一棵树,n个点,m条边.让从中选k个点,使得从a1到a2,a2到a3,ak-1到ak的路 ...
- BZOJ4399 魔法少女LJJ【线段树合并】【并查集】
Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了 LJJ感叹道"这里真是个迷人的绿色世界,空气清新.淡雅 ...
最新文章
- 区块链教程Fabric1.0源代码gRPC(Fabric中注册的gRPC Service)一
- SqlHelper.cs 使用时要注意的地方
- java 隐藏文件_java-如何仅列出jtree中的非隐藏文件和非系...
- TypeScript 变量声明
- 字节跳动python面试_【字节跳动Python面试】生平遇到最好的面试体验-看准网
- JavaFX布局中图片在表格中无法被自适应缩小?
- 理解node.js(Understanding node.js)
- 【Flink】数据传输 挖个坑 把自己埋了 ClassCastException String cannot be cast to [LJava.lang.String
- 推荐12个非常不错而且免费的后台管理HTML模板
- mysql共享锁与排他锁
- 7.29~8.2 广州软件所-实习工作日记
- 为什么做网站一般不用服务端控件?
- Python爬虫Scrapy入门
- python实现自适应中值滤波器
- 使用Foxmail登录阿里企业邮箱(钉钉邮箱)
- 微信小程序之移动端适配
- linux下编译和安装log4cxx,ubuntu下log4cxx安装使用
- VS Code开源软件介绍——史上最优秀的 IDE ?
- 如何提取伴奏?1分钟让你知道伴奏提取软件手机版有哪些
- Codeforces 513G1 or 513G2 Inversions problem DP
热门文章
- HISTORY OF ETHEREUM SECURITY VULNERABILITIES, HACKS AND THEIR FIXES
- APK加壳【3】通用内存加载dex方案分析
- 美团Android资源混淆保护实践
- sql安装目录下log文件夹_Linux安装Hive数据仓库工具
- homeassistant树莓派cpu_集成ESP8266的WiFi RGB灯泡接入Home Assistant
- c malloc 头文件_C语言提高篇_malloc,realloc和calloc的区别
- 关于c++静态类的说法
- 使用C/C++解析json文件
- C++的黑科技 利用一个字符对字符串进行分离
- 最大匹配 人员分配[邻接表]