51nod1307 绳子与重物
来源:互联网 发布:期货数据分析 编辑:程序博客网 时间:2024/03/29 14:38
链接:http://www.51nod.com/onlineJudge/submitDetail.html#!judgeId=61547
题意:中文题。。。
分析:直接二分就可以了,dfs判断。。但是!出题人说有O(n)的算法,我不甘心。下次补充。
PS:并查集做法:从叶子向根统计子树和,如果当前子树和大于根的负重,就从最后一个添加的点开始删除。详见代码。
代码1:
#include<map>#include<set>#include<cmath>#include<queue>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=50010;const int MAX=151;const int MOD=1000000007;const int MOD1=100000007;const int MOD2=100000009;const int INF=2100000000;const double EPS=0.00000001;typedef long long ll;typedef unsigned long long uI64;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int bo,tot,d[N],h[N],c[N],w[N],pre[N];void add(int x,int y) { d[tot]=y;pre[tot]=h[x];h[x]=tot++;}ll dfs(int x,int y) { ll sum=w[x]; if (x>y) return 0; for (int i=h[x];i!=-1;i=pre[i]) sum+=dfs(d[i],y); if (x&&sum>c[x]) bo=0; return sum;}int main(){ int i,n,x,l,r,mid; scanf("%d", &n); tot=0; memset(h,-1,sizeof(h)); for (i=1;i<=n;i++) { scanf("%d%d%d", &c[i], &w[i], &x); x++;add(x,i); } l=0;r=n+1;mid=(l+r)/2; while (l+1<r) { bo=1;dfs(0,mid); if (bo) { l=mid;mid=(l+r)/2; } else { r=mid;mid=(l+r)/2; } } printf("%d\n", l); return 0;}
代码2:
#include<map>#include<set>#include<cmath>#include<queue>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=50010;const int MAX=151;const int MOD=1000000007;const int MOD1=100000007;const int MOD2=100000009;const int INF=2100000000;const double EPS=0.00000001;typedef long long ll;typedef unsigned long long uI64;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}ll c[N],w[N],ww[N];int k,p[N],fa[N];int tot,d[N],h[N],pre[N];void add(int x,int y) { d[tot]=y;pre[tot]=h[x];h[x]=tot++;}int find_fa(int x) { if (fa[x]==x) return x; return fa[x]=find_fa(fa[x]);}void updata(int x) { for (int i=h[x];i!=-1;i=pre[i]) { w[x]+=w[d[i]];fa[d[i]]=x; } while (w[x]>c[x]) { w[find_fa(k)]-=ww[k];k--; }}int main(){ int i,n; scanf("%d", &n); tot=0; memset(h,-1,sizeof(h)); for (i=1;i<=n;i++) { scanf("%lld%lld%d", &c[i], &ww[i], &p[i]); p[i]++;fa[i]=i;add(p[i],i);w[i]=ww[i]; } k=n; for (i=n;i>0;i--) updata(i); printf("%d\n", k); return 0;}
0 0
- 51nod1307 绳子与重物
- 51nod1307 绳子与重物
- 51NOD1307 绳子与重物 【并查集】
- 二分+dfs——51nod1307 绳子与重物
- 51nod 1307 绳子与重物
- 51nod 1307 绳子与重物
- 51nod 1307 绳子与重物
- 绳子与重物
- 51Nod-1307-绳子与重物
- 51nod 1307 绳子与重物【二分+Dfs】
- 51nod 1307 绳子与重物 【二分+dfs】
- 51nod 1307 绳子与重物 【二分/并查集】
- 51nod 1307 绳子与重物 二分+dfs
- 51nod 1307 绳子与重物 二分+dfs / 并查集
- 51nod 1307 绳子与重物【并查集】【搜索】【二分法】
- 51nod 1307 绳子与重物 (标记父节点更新即可)
- 一根绳子
- 剪绳子
- android 学习系列教程
- QT 如何改图可执行文件图标
- Volley缓存方式下载图片
- ERP原理
- code
- 51nod1307 绳子与重物
- 自动测试常用的判定方法
- 探讨一下C语言中char类型数组的移位操作
- Android源码剖析之------常见Window的创建过程
- Android基础之自己创建活动
- Java中的装箱,拆箱详解
- 上拉加载下拉刷新的RecyclerView可添加headerView
- c++数组的几个有趣性质
- 一点思考