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了三次还不知所云 代码
随机推荐
- 【转】MOCK测试
mock测试:就是在测试过程中,对于某些不容易构造或者 不容易获取的对象,用一个虚拟的对象[mock对象]来创建以便测试的测试方法. mock对象:这个虚拟的对象就是mock对象. mock对象就是真 ...
- php yaf框架扩展实践五——数据层
从狭义角度上来理解数据层就是数据库,比较广义的理解来看数据库.远程数据.文件等都可以看做数据层.项目初期的时候一般单一的数据库就可以了,随着流量的增大就要对数据层做很多的改进,例如增加从库分散读压力, ...
- php中数组中&的问题
1.代码: <?php $arr = array('one','two','three'); foreach ($arr as $value){ echo 'Value:'.$value.'&l ...
- const在指针中的用法
一.指向const对象的指针---对象不能修改 方式1 int value1 = 3; const int *p1 = &value1; *p1 = 5; //错误,不能修改const指向对象 ...
- Ubuntu安装qBittorrent
qBitTorrent是Ubuntu Linux中最受欢迎的P2P软件之中的一个. 出自一名法国大学生之手的qBitTorrent功能强大.界面精美.操作直观. qBitTorrent是Linux中最 ...
- mysql数据库导入到oracle数据库
首先,写一个cmd脚本 xx.cmd sqlldr username/password control=xx.ctl errors=10000000 direct=y 再写一个bat脚本xx.bat ...
- python框架Scrapy中crawlSpider的使用
一.创建Scrapy工程 #scrapy startproject 工程名 scrapy startproject demo3 二.进入工程目录,根据爬虫模板生成爬虫文件 #scrapy genspi ...
- 分布式计算 要不要把写日志独立成一个Server Remote Procedure Call Protocol
w https://en.wikipedia.org/wiki/Remote_procedure_call In distributed computing a remote procedure ca ...
- python imageio 图片生成gif
#!/bin/python3 import matplotlib.pyplot as plt import imageio,os TIME_GAP=0.075 #两帧之间的时间间隔,秒为单位 FILE ...
- 洛谷 [BJOI2012]最多的方案
洛谷 这题是旁边同学介绍的,听他说记忆化搜索可以过... 不过我还是老老实实的想\(dp\)吧- 先看看数据范围,\(n\leq10^{18}\)相当于\(n \leq fib[86]\). 以前打\ ...