题目描述:

$zhx$有一个棵$n$个点的树,每条边有个权值。

定义一个连通块为一个点集与使这些点连通的所有边(这些点必须连通)。

定义一个连通块的权值为这个连通块的边权和(如果一个连通块只包含一个点,那么它的权值为$0$)。

$zhx$想找一个包含$1$号点的连通块送给他的妹子,所以他希望你求出包含$1$号点的所有连通块中权值第$k$小的连通块的权值。

题解:

非常裸的可持久化可并堆。

经典的$k$短路要求维护绕多远+终点,而它维护总边权+可选边集。

维护边集时需要可持久化可并堆。

还是经典操作,要么扔掉上一条边换上次优,要么在边集中找一个最优然后更新边集。

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
const int MOD = ;
const int M = *N;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
int n,k,rt[N],wy[M];
ll ww[M];
struct edc
{
int x;
ll d;
edc(){}
edc(int x,ll d):x(x),d(d){}
friend bool operator < (edc a,edc b)
{
return a.d>b.d;
}
}tp;
int tot,tw;
struct node
{
int ls,rs,dis,tl;
ll v;
}p[M];
int merge1(int x,int y)
{
if(!x||!y)return x+y;
if(p[x].v>p[y].v)swap(x,y);
p[x].rs = merge1(p[x].rs,y);
if(p[p[x].ls].dis<p[p[x].rs].dis)swap(p[x].ls,p[x].rs);
p[x].dis=p[p[x].rs].dis+;
return x;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(p[x].v>p[y].v)swap(x,y);
int u = ++tot;
p[u] = p[x],p[u].rs = merge(p[u].rs,y);
if(p[p[u].ls].dis<p[p[u].rs].dis)swap(p[u].ls,p[u].rs);
p[u].dis = p[p[u].rs].dis+;
return u;
}
priority_queue<edc>q;
ll ans;
int main()
{
freopen("tt.in","r",stdin);
read(n),read(k);
for(int f,w,i=;i<n;i++)
{
read(f),read(w);
p[++tot].dis=,p[tot].tl=i+,p[tot].v=w;
rt[f] = merge1(rt[f],tot);
}
k--;
tw=;
ww[tw] = p[rt[]].v;
wy[tw] = rt[];
q.push(edc(,ww[]));
while(k&&!q.empty())
{
tp = q.top();
q.pop();
k--;
int u = tp.x;
ans = ww[u];
if(!k)break;
int ls = p[wy[u]].ls,rs = p[wy[u]].rs;
int tmp = merge(ls,rs);
if(tmp)
{
tw++;
ww[tw] = ww[u]-p[wy[u]].v+p[tmp].v;
wy[tw] = tmp;
q.push(edc(tw,ww[tw]));
}
tw++;
wy[tw] = merge(tmp,rt[p[wy[u]].tl]);
ww[tw] = ww[u]+p[wy[tw]].v;
if(wy[tw])q.push(edc(tw,ww[tw]));
}
printf("%lld\n",ans%MOD);
return ;
}

OVOO的更多相关文章

  1. 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)

    Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...

  2. IntelliJ IDEA sass环境配置及常见报错处理

    1.下载安装ruby,网上教程很多的,安装完之后在命令行输入ruby -v检查一下是否安装成功了.(注意安装的时候要勾选第二项).

  3. GitHub创建个人主页

    在GitHub,一个项目对应唯一的Git版本库,创建一个新的版本库就是创建一个新的项目.访问仪表板(Dashboard)页面,如图3-1,可以看 到关注的版本库中已经有一个,但自己的版本库为零.在显示 ...

  4. 面向初学者的指南:创建时间序列预测 (使用Python)

    https://blog.csdn.net/orDream/article/details/100013682 上面这一篇是对 https://www.analyticsvidhya.com/blog ...

随机推荐

  1. c语言函数参考

                                                                                                        ...

  2. 【弱的C艹之路。。未完待续】

    [弱的C艹之路] 数据范围 unsigned int 0-4294967295 int 2147483648-2147483647 unsigned long 0-4294967295 long 21 ...

  3. c++ 语法解析

    大小 size()是取字符串长度的,跟length()用法相同 size_t其实是一种类型,类似于无符号整形(unsignted int).可以理解成unsignted int size,当unsig ...

  4. web 另类方法实现“另存为”功能

    HTML5 的 FileReader 带给我们很强大的文件只读访问能力,可是在 HTML5 新增的 JS 中却没有发现有方便的另存到本地文件的相关 API,以往的办法要么调用浏览器的 save as ...

  5. python正则表达式多次提取数据(一个规则提取多组数据)

    import re ttt='"FileName":"陈雪凝 - <em>绿色<\/em>","AlbumID":& ...

  6. 515 Find Largest Value in Each Tree Row 在每个树行中找最大值

    在二叉树的每一行中找到最大的值.示例:输入:           1         /  \        3   2       /  \    \        5   3    9 输出: [ ...

  7. 74LVC2G241双缓冲3态驱动器

  8. 【转载】(0, eval)(‘this’)

    var window = this || (0, eval)('this') 在avalon源码中有这么一行代码,var window = this很容易理解 这里复习一下Global Object: ...

  9. Pycharm中pygame报错

    什么鬼???我记得刚安装过啊-.. 并且本机只有一个python3.5,环境变量之前都是正常,我去折腾了大半天,原来在pycharm中安装模块是在如下所示图中 以后如果没有安装模块,都可以在这里进行安 ...

  10. 关于发布WP 8.1应用信息不匹配问题的解决办法

    错误提示:   与此更新关联的程序包标识符与已上传程序包中的标识符不匹配: The package identity associated with this update doesn't match ...