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了三次还不知所云 代码
随机推荐
- spring mvc 3.0 实现文件上传功能
http://club.jledu.gov.cn/?uid-5282-action-viewspace-itemid-188672 —————————————————————————————————— ...
- EasyUI DataGrid 编辑单元格
如下图: 现改为单击某个单元格只对此单元格进行可编辑 <TABLE>标记添加 onClickCell <table id="dg" class="eas ...
- C语言 百炼成钢27
/* 题目63:编写C++程序完成以下功能: (1)声明一个纯虚函数类Shape(形状),其中包含来计算面积.计算周长的方法: (2)从Shape派生两个类矩形和圆形: (3)从矩形派生正方形: (4 ...
- PHP-preg_replace过滤字符串代码
$str=preg_replace("/\s+/", " ", $str); //过滤多余回车 $str=preg_replace("/& ...
- UTF8转换为GB编码gb2312转换为utf-8
这个方法是用windows的字符集转换的,跟sybase 的unicode码表可能在某些符号上有差别,对于大部分字符来说,尤其是 汉字,应该不会有问题的,如果要求比较高的话,可以买sybase的 un ...
- ==和Equal()的区别
我们在编程的时候,经常会遇到判断两个对象是否相等的情况.说到判断两个对象是否相等,就不得不说对象的类型和对象在内存中的存储情况. 对象类型可以分为值类型和引用类型: 值类型包括:简单类型.结构类型.枚 ...
- python import错误 SyntaxError: invalid syntax
导入一个叫service-listener.py的文件是一直遇到错误: SyntaxError: invalid syntax 单独运行service-listener这个文件时,没有问题,只是不能被 ...
- js 代码优化 (写的可以)
Javascript是一门非常灵活的语言,我们可以随心所欲的书写各种风格的代码,不同风格的代码也必然也会导致执行效率的差异,开发过程中零零散散地接触到许多提高代码性能的方法,整理一下平时比较常见并且容 ...
- 在系统重装后为什么ChemDraw用不了
作为一款非常受欢迎的化学绘图软件ChemDraw需要在满足运行条件的电脑上运行,但是一些用户发现自己在给自己的电脑重装系统之后,ChemDraw运行不了呢.导致ChemDraw用不了的原因比较多样,不 ...
- hdu 3681(bfs+二分+状压dp判断)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...