51nod 1307 绳子与重物【并查集】【搜索】【二分法】
来源:互联网 发布:手机电子秤软件下载 编辑:程序博客网 时间:2024/04/29 14:43
- 题目大意
- 思路
- 思路1 二分DFS
- 思路2 并查集
- 代码1 二分DFS
- 代码2 并查集
- Hit
题目大意
传送门
给出
每个绳子的承重Ci
小球的重量Wi
小球挂在那个小球上Pi
问最多挂多少个绳子而不会出现绳子断掉的情况。
思路
本文是看教程:O(n)可以解决的2道题
习题的第二题。
思路1 二分+DFS
按照我的想法,对绳子的列表进行二分
思路2 并查集
使用路径压缩之后并查集的平摊复杂度为
使用并查集+DFS的方法复杂度可以看做是
使用并查集的时候要将维护建树的过程:
首先建树的时候维护元素node[i].W_S
如果以当前结点为根的子树的重量和大于了承重,就要删除最后一个元素(为什么是最后一个元素?因为重物是按照顺序添加的,可以从最后一个慢慢删,仅仅针对此题)。
代码1 二分+DFS
#include<iostream>#include<stdio.h>#include<vector>using namespace std;#define INF 1<<30#define maxn 50005int W[maxn];int C[maxn];int P[maxn];int N;int W_Sum[maxn];//绳子i现在的承重vector<int> G[maxn];//与绳子i相连的点的集合//这时候物体的结构已经被储存在了vector中bool dfs(int u){ W_Sum[u] = W[u]; for(int i = 0; i<G[u].size(); i++) { if(!dfs(G[u][i])) return 0; W_Sum[u] += W_Sum[G[u][i]]; } return W_Sum[u] <= C[u];}bool Solve(int x){ for(int i = 0; i <= x; i++) G[i].clear();//将物体i挂在的绳子P[i]上的物体clear for(int i = 1; i <= x; i++) G[P[i]].push_back(i); //物体i 挂在 绳子P[i]上 return dfs(0);}int main(){ while(~scanf("%d",&N)) { for(int i = 1; i <= N; i++) { scanf("%d%d%d",&C[i],&W[i],&P[i]),P[i]++;//分别是 绳子的最大负重 物体的重量 挂在哪个绳子上 } C[0] = INF;//将根节点的最大承重设置为无限大 int l = 0; int r = N; while(l<r) { //printf("%d %d\n",l,r); int mid = (l+r+1)/2; if(Solve(mid)) { l = mid; } else r = mid-1; } printf("%d\n",l); }}
代码2 并查集
#include<iostream>#include<stdio.h>#include<vector>using namespace std;#define INF 1<<30#define maxn 50005int N;struct Node{ int C,W,P,W_S;} node[maxn];int fa[maxn]; //fa[i]表示结点i的父节点//查找结点i的源头int Find_fa(int i){ if(fa[i]==i) return fa[i]; return fa[i] = Find_fa(fa[i]);}int main(){ while(~scanf("%d",&N)) { for(int i = 1; i <= N; i++) { scanf("%d%d%d",&node[i].C, &node[i].W, &node[i].P);//分别是 绳子的最大负重 物体的重量 挂在哪个绳子上 node[i].P++; node[i].W_S = node[i].W; //Init fa[i] = i; } // int ans = N; for(int i = N; i ; i--) { while(node[i].W_S > node[i].C) //如果当前子树的重量 大于 结点的负重,就从最后一个添加的点开始删除 { int k = Find_fa(ans); node[k].W_S -= node[ans].W;//将node[ans]从子树中去掉 ans --; } node[node[i].P].W_S += node[i].W_S;//将以node[i]为结点的子树的总重量 加入到 以node[i]的父节点为子树的总重量 中 fa[i] = node[i].P;//建树 } printf("%d\n",ans); }}
Hit
将物体由-1开始变成0开始
阅读全文
0 0
- 51nod 1307 绳子与重物【并查集】【搜索】【二分法】
- 51nod 1307 绳子与重物 【二分/并查集】
- 51nod 1307 绳子与重物 二分+dfs / 并查集
- 51NOD1307 绳子与重物 【并查集】
- 51nod 1307 绳子与重物
- 51nod 1307 绳子与重物
- 51nod 1307 绳子与重物
- 51Nod-1307-绳子与重物
- 51nod 1307 绳子与重物【二分+Dfs】
- 51nod 1307 绳子与重物 【二分+dfs】
- 51nod 1307 绳子与重物 二分+dfs
- 51nod 1307 绳子与重物 (标记父节点更新即可)
- 51nod1307 绳子与重物
- 51nod1307 绳子与重物
- 绳子与重物
- 二分+dfs——51nod1307 绳子与重物
- 51nod 1204:Parity 并查集
- 51nod 1191-贪心+并查集
- 浅析iServer地址匹配服务
- 用quartz做定时任务时和shiro中用到的quartz包版本不一致导致的冲突的解决方法
- :nth-child(index)和nth-child(index)选择器的区别
- JDK7异常处理
- 杂记(前端安全以及性能优化)
- 51nod 1307 绳子与重物【并查集】【搜索】【二分法】
- @propery (class,...) 小记,静态函数另类调用方法
- IBM Platform Symphony:功能强大的高效大数据分析平台
- Java语言基础学习笔记(一)
- 神经网络之keras/tf框架实现
- [NOIP模拟赛]填充表格
- mt6735修改闪光灯阀值
- kendo ui 访问数据库数据,绘制jsp页面
- Hadoop之为何不使用RAID