EOJ - 3631 Delivery Service 2018.8华师大月赛(树链剖分+贪心)
链接:https://acm.ecnu.edu.cn/contest/103/problem/D/
题意:给你一棵无向边连接的树,边的权值可以任意互换。有m次运输,每次的花费是点u到v路径上边的权值和。
必须在全部运输开始前安排好边的权值,求m次运输总的最小花费。
分析:肯定是边被覆盖次数越多的边优先得到较小的权值。轻重链剖分之后,用线段树或树状数组维护每点的覆盖次数。最后对边和权值排序后贪心选取即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define lson rt<<1
#define rson rt<<1|1
#define Lson l,m,lson
#define Rson m+1,r,rson
typedef long long LL;
using namespace std;
const int maxn =2e5+;
struct Edge{
int to,next;
}E[*maxn];
int n,head[maxn],tot;
int cnt,idx,size[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],id[maxn],rnk[maxn];
int e[maxn][];
int W[maxn];
struct Node{
int sum,add;
}tree[maxn<<];
void init()
{
cnt=idx=tot=;
memset(head,-,sizeof(head));
dep[]=,fa[]=,size[]=;
memset(son,,sizeof(son));
}
void AddEdge(int u,int v)
{
E[tot] = (Edge){v,head[u]};
head[u]=tot++;
}
void dfs1(int u)
{
size[u]=;
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=fa[u]){
fa[v]=u;
dep[v]=dep[u]+;
dfs1(v);
size[u]+=size[v];
if(size[son[u]]<size[v]) son[u]=v;
}
}
} void dfs2(int u,int topu)
{
top[u]= topu;
id[u] = ++idx;
rnk[idx] = u;
if(!son[u]) return;
dfs2(son[u],top[u]);
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
} void pushup(int rt){ tree[rt].sum = tree[lson].sum + tree[rson].sum; }
void pushdown(int l,int r,int rt){
if(tree[rt].add){
tree[lson].add += tree[rt].add;
tree[rson].add += tree[rt].add;
int m = (l+r)>>;
tree[lson].sum += (m-l+)*tree[rt].add;
tree[rson].sum += (r-m)*tree[rt].add;
tree[rt].add =;
}
} void build(int l,int r,int rt)
{
tree[rt].add = ;
if(l==r){
tree[rt].sum = ;
return;
}
int m = (l+r)>>;
build(Lson);
build(Rson);
pushup(rt);
} void update(int L,int R,int v,int l=,int r=n,int rt=){
if(L<=l && R>=r){
tree[rt].sum +=(r-l+)*v;
tree[rt].add +=v;
return ;
}
pushdown(l,r,rt);
int m =(l+r)>>;
if(L<=m) update(L,R,v,Lson);
if(R>m) update(L,R,v,Rson);
pushup(rt);
} int query(int p,int l=,int r=n,int rt=){ //单点
if(l==r) return tree[rt].sum;
pushdown(l,r,rt);
int m = (l+r)>>,ans=;
if(p<=m) ans= query(p,Lson);
else ans =query(p,Rson);
pushup(rt);
return ans;
} void UPDATE(int u,int v,int w=)
{
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(id[top[u]],id[u],w);
u = fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
update(id[son[u]],id[v],w);
} int vis[maxn]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int m,q,u,v;
char op[];
while(scanf("%d",&n)==){
init();
for(int i=;i<n;++i){
scanf("%d%d%d",&u,&v,&W[i]);
AddEdge(u,v);
AddEdge(v,u);
e[i][] =u, e[i][] = v;
}
dfs1();
dfs2(,);
build(,n,);
for(int i=;i<n;++i){
if(dep[e[i][]]>dep[e[i][]]) swap(e[i][],e[i][]);
}
scanf("%d",&q);
while(q--){
scanf("%d%d",&u,&v);
UPDATE(u,v);
}
sort(W+,W+n);
LL res=;
for(int i=;i<n;++i){
v = e[i][];
vis[i] = query(id[v]);
}
sort(vis+,vis+n);
for(int i=;i<n;++i){
res+= (LL)W[i]*vis[n-i];
}
printf("%lld\n",res);
}
return ;
}
EOJ - 3631 Delivery Service 2018.8华师大月赛(树链剖分+贪心)的更多相关文章
- 【UOJ#435】【集训队作业2018】Simple Tree 分块+树链剖分
		题目大意: 有一棵有根树,根为 1 ,点有点权.现在有 m 次操作,操作有 3 种:1 x y w ,将 x 到 y 的路径上的点点权加上 w (其中 w=±1w=±1 ):2 x y ,询问在 x ... 
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
		裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ... 
- bzoj 3631 松鼠的新家 (树链剖分)
		链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3631 思路: 直接用树链剖分求每一次运动,因为这道题只需要区间增添,单点求值,没必要用线段 ... 
- [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP
		题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ... 
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
		3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ... 
- UOJ#435. 【集训队作业2018】Simple Tree 树链剖分,分块
		原文链接www.cnblogs.com/zhouzhendong/p/UOJ435.html 前言 分块题果然是我这种蒟蒻写不动的.由于种种原因,我写代码的时候打错了很多东西,最致命的是数组开小了.* ... 
- ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat  (树链剖分+线段树)
		题目链接:https://nanti.jisuanke.com/t/31714 题意:给你一棵树,初始全为0,有四种操作: 1.u-v乘x 2.u-v加x 3. u-v取反 4.询问u-v ... 
- 2018.11.09 codeforces487E. Tourists(tarjan+树链剖分)
		传送门 先把边双连通分量用圆方树一样的方法缩点,然后把新建的树树剖维护. 注意对于边双连通分量需要维护动态最小值,可以用multisetmultisetmultiset. 代码: #include&l ... 
- 2018.10.30 NOIP训练 【模板】树链剖分(换根树剖)
		传送门 纯粹是为了熟悉板子. 然后发现自己手生了足足写了差不多25min而且输出的时候因为没开long longWA了三次还不知所云 代码 
随机推荐
- a标签点击事件
			onclick="detail(this,'${vo.id}')" function detail(obj,id){ var lb = $("#lb").val ... 
- 修改net基本三层 动软生产
			控制层(dal) 模型层-实体类(Model) 显示层-web 
- 禁用LinkButton的方法
			1.服务器端,使用Enabled属性即可 <asp:LinkButton ID="lbtn" runat="server" Enabled="f ... 
- ListView setOnItemClickListener无效原因具体分析
			前言 近期在做项目的过程中,在使用listview的时候遇到了设置item监听事件的时候在没有回调onItemClick 方法的问题. 我的情况是在item中有一个Buttonbutton. 所以不会 ... 
- 【VBA】合并多个excel文件
			From http://www.zhihu.com/question/20366713 VBA代码如下: Sub 工作薄间工作表合并() Dim FileOpen Dim X As Integer A ... 
- iOS从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题
			本文转载至 http://blog.csdn.net/woaifen3344/article/details/41284319 navios 如果有朋友遇到从当前隐藏导航界面push到下一个显示导航界 ... 
- POJO应用框架:Spring与EJB3.0的比较
			英文原文地址:http://www.onjava.com/pub/a/onjava/2005/06/29/spring-ejb3.html中文地址:http://www.matrix.org.cn/r ... 
- Python 基础之列表去重的几种玩法
			列表去重 1.方法1 借助一个临时列表 ids = [1,2,3,3,4,2,3,4,5,6,1] news_ids = [] for id in ids: if id not in news_ids ... 
- Camlistore名词解释
			Terminology 名词解释 To stay sane and communicate effectively we try hard to use consistent terminology ... 
- vue+node+mongoDB 火车票H5(二)---vux和less的配置
			vue基本环境配置好之后,就可以开始开发页面了 开发页面之前先了解一下项目结构,原始的目录结构为: config是配置文件,环境配置好了开发阶段可以不再去修改了,node_modules文件夹是打包的 ... 
