玛迪网站建设,网络整合营销,温州网站链接怎么做,自己买服务器做视频网站正题
题目链接:https://www.luogu.com.cn/problem/P1552 题目大意
一个nnn个点森林#xff0c;每个点有价值和代价#xff0c;选择一个点并在这个点的子树中选择一些点使得。 选择的点数∗该点的价值选择的点数*该点的价值选择的点数∗该点的价值最大且选择的点的代价之和不…正题
题目链接:https://www.luogu.com.cn/problem/P1552 题目大意
一个nnn个点森林每个点有价值和代价选择一个点并在这个点的子树中选择一些点使得。
选择的点数∗该点的价值选择的点数*该点的价值选择的点数∗该点的价值最大且选择的点的代价之和不超过mmm。 解题思路
我们对于每个点我们将所有子节点处理完后将子节点的左偏树合并然后不停弹出代价最大的点知道代价之和小于等于mmm即可。
时间复杂度O(nlogn)O(n\log n)O(nlogn) codecodecode
#includecstdio
#includecstring
#includealgorithm
#define ll long long
using namespace std;
const ll N110000;
ll n,m,val[N],lead[N],sum[N],ans;
struct Left_Tree{ll t[N][2],fa[N],dis[N];#define ls t[x][0]#define rs t[x][1]ll Get(ll x){return (fa[x]x)?(x):(fa[x]Get(fa[x]));}ll Merge(ll x,ll y){if(!x||!y) return xy;if(val[x]val[y]||(val[x]val[y]xy))swap(x,y);rsMerge(rs,y);if(dis[ls]dis[rs])swap(ls,rs);fa[rs]fa[ls]x;dis[x]dis[rs]1;sum[x]sum[rs]sum[ls]val[x];return x;}void Del(ll x){val[x]0;fa[ls]ls;fa[rs]rs;fa[x]Merge(ls,rs);}#undef ls#undef rs
}T;
struct edge_node{ll to,next;
}a[N];
ll ls[N],tot;
bool k[N];
void addl(ll x,ll y)
{a[tot].toy;a[tot].nextls[x];ls[x]tot;
}
ll dfs(ll x){ll siz1;for(ll ils[x];i;ia[i].next){ll ya[i].to;sizdfs(y);T.Merge(T.Get(x),T.Get(y));}while(sum[T.Get(x)]m)T.Del(T.Get(x)),siz--;ansmax(ans,siz*lead[x]);return siz;
}
int main()
{scanf(%lld%lld,n,m);for(ll i1;in;i){ll x;scanf(%lld%lld%lld,x,val[i],lead[i]);sum[i]val[i];T.fa[i]i;if(x)addl(x,i);else k[i]1;}for(ll i1;in;i)if(k[i]) dfs(i);printf(%lld,ans);
}