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
原创粉丝点击