【CF671D】Roads in Yusland

技术【CF671D】Roads in Yusland 【CF671D】Roads in Yusland题目
题目链接:https://codeforces.com/problemset/problem/

【CF671D】尤斯兰的道路

题目

题目链接:https://codeforces.com/problemset/problem/671/D

给定一棵\(n\)个点的以\(1\) 为根的树。

有\(m\)条路径\((x,y)\),保证\(y\)是\(x\)或\(x\)的祖先,每条路径有一个权值。

你要在这些路径中选择若干条路径,使它们能覆盖每条边,同时权值和最小。

《10^5\)。时报》

思路

设\(f[x]\)表示覆盖点\(x\)子树内所有边以及\(x\)与其父亲的边的最小代价。

但是很明显\(f[x]\)不能简单转移。因为有可能花更多代价,覆盖\(x\)的祖先更多,这种情况是可能最优的。

所以可以对每一个点维护一个堆,存可能的最优解。

考虑点\(y\)怎么转移到其父亲\(x\)。对于\(y\)的堆中一个代价为\(k\)的方案,合并到\(x\)后,其代价应该是\(k \\ sum _ { z \\ in \\ text { son }(x),z \\ neq y \u f[z]\)。

也就是说,\(y\)的所有方案只需要同时加上一个常数,然后扔到\(x\)的堆里就好了。直接上左偏树,然后需要搞一个子树加的标记。

但是当某一个方案覆盖不到\(x\)与其父亲的边的时候,这个方案就需要删掉了。在每次合并完后不断判断堆顶是否需要删掉即可。

新建一个虚根连向\(1\),再加一条代价为\(0\) 的路径,最后输出虚根的\(f\)即可。

时间复杂度\(0(n \ log m)\)。

代码

#包含位/stdc .h

#定义国会议员制作对

#首先定义船方不负担装货费用

#定义硒秒

使用命名空间标准;

typedef长ll长

常量整数N=300010

整数n,m,tot,头[N],rt[N],副[N];

ll f[N];

布尔标志;

vectorpairint,int a[N];

结构边缘

{

(同Internationalorganizations)国际组织紧挨着;

} e[N * 2];

void add(int from,int to)

{

e[ tot]=(edge){head[from],to };

从头开始。

}

结构左树

{

int tot,dis[N],pos[N],lc[N],RC[N];

懒惰的;

int insert(pairint,int b)

{

tot val[tot]=b . se;pos[tot]=b . fi;

返回小孩

}

无效下推(int x)

{

如果(懒惰[x])

{

if (lc[x]) val[lc[x]]=lazy[x],lazy[LC[x]]=lazy[x];

if (rc[x]) val[rc[x]]=lazy[x],lazy[RC[x]]=lazy[x];

lazy[x]=0;

}

}

int merge(int x,int y)

{

if(!x ||!y)返回x | y;

下推;下推(y);

if(val[x]val[y]| |(val[x]==val[y]xy))swap(x,y);

rc[x]=merge(rc[x],y);

if(dis[RC[x]]dis[LC[x]]交换(LC[x],RC[x]);

dis[x]=dis[RC[x]]1;

返回x;

}

int pop(int x)

{

下推;

返回合并(lc[x],RC[x]);

}

}点亮;

无效dfs(int x,int fa)

{

dep[x]=dep[fa]1;

for(int I=0;i(int)a[x].size();(一)

rt[x]=lit.merge(rt[x],lit)。插入(a[x][I]);

for(int I=head[x];~我;i=e[i]。下一个)

{

int v=e[i].去;

if (v!=fa)

{

dfs(v,x);f[x]=f[v];

如果(标志)返回;

真实的懒惰[rt[v]]-=f[v];真实的val[rt[v]]-=f[v];

rt[x]=lit.merge(rt[x],rt[v]);

}

}

真实的lazy[rt[x]]=f[x];真实的val[rt[x]]=f[x];

而(rt[x]dep[lit]。pos[rt[x]]=dep[x])

rt[x]=点亮。pop(rt[x]);

if(!rt[x]){ flag=1;返回;}

f[x]=升。val[rt[x]];

}

int main()

{

memset(head,-1,sizeof(head));

scanf('%d%d ',n,m);

for (int i=1,x,y;在;(一)

{

scanf('%d%d ',x,y);

添加(x,y);添加(y,x);

}

n;add(n,1);

for (int i=1,x,y,z;I=m;(一)

{

scanf('%d%d%d ',x,y,z);

a[x].push_back(mp(y,z));

}

a[1].push_back(mp(0,0));

真实的dis[0]=-1;dep[0]=-1;

dfs(n,0);

如果(标志)cout '-1 ';

else coutf[n];

返回0;

}

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/37483.html

(0)

相关推荐

  • Python代码列表怎么求并集,交集,差集

    技术Python代码列表怎么求并集,交集,差集本篇内容介绍了“Python代码列表怎么求并集,交集,差集”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希

    攻略 2021年11月12日
  • 抖音点赞3元100个,抖音刷点赞最低价?

    技术抖音点赞3元100个,抖音刷点赞最低价?抖音点赞量的价钱和你选的平台是不一样的,有些平台点赞100条可能需要15元,有些可能只需要10元,这其中的价格差是很大的,但是点赞量的质量是一样的。
    抖音点赞量的价格是由你购买

    测评 2021年10月22日
  • 数据库操作日志(存日志用什么数据库)

    技术数据库中如何实现日志转储脚本这篇文章主要为大家展示了“数据库中如何实现日志转储脚本”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“数据库中如何实现日志转储脚本”这篇文章吧。

    攻略 2021年12月13日
  • 哪些业务适合租用香港服务器

    技术哪些业务适合租用香港服务器虽然大多数海外建站能从租用香港服务器中获得很多好处。然而,很多网站并不需要一开始就租用高性能的香港服务器,那么哪些业务适合使用香港服务器呢,下面就来介绍一下以下几个业务类型更适合使用香港服务

    礼包 2021年10月19日
  • 去上学用英语怎么说,我今天没有去学校用英文怎么写

    技术去上学用英语怎么说,我今天没有去学校用英文怎么写今天没去学校I didnt go to school today.school 英[sku:l]美[skul]n. 学校; 学院; 上学; 群;vt. 训练,锻炼; 教

    生活 2021年10月26日
  • css如何做直角梯形

    技术css如何做直角梯形本篇内容主要讲解“css如何做直角梯形”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“css如何做直角梯形”吧! 在css中

    攻略 2021年12月4日