UVALive 7338 (树链剖分+线段树)

时间:2022-04-18 16:20:54

Problem Toll Management IV

题目大意

  给一张n个点m条边的无向图,有边权。数据保证前n-1条边构成了一棵最小生成树。

  要求对于每条边求出其边权上下最多浮动范围,使得最小生成树的形态不变(每次只改变一条边的权值)。

  n<=10000,m<=1000000

解题分析

  我们称在最小生成树上的边为实边,不在最小生成树上的边为虚边。

  对于虚边u-->v,其权值一定可以无限增加。可以发现这条虚边不会影响u--v路径外的点所构成最小生成树的形态。假设u-->v路径上的边最大权值为w,那么当这条虚边的权值小于w时,那么这条虚边将会取代权值为w的边,成为实边。即这条虚边权值的下限为w。

  对于实边u-->v,其权值一定可以无限减小。假设不选用这条实边,那么最小生成树将被分成两部分。那么连接这两部分的虚边将有可能替代这条实边。假设有可能的虚边中权值最小为w,那么这条实边的上限为w。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define V 10008
#define E 200008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/
int n,m,sum,cnt;
int lt[V],dep[V],son[V],w[V],rk[V],fa[V],top[V],size[V];
int a[E],b[E]; struct line{
int u,v,w,nt;
line(int u=,int v=,int w=,int nt=):u(u),v(v),w(w),nt(nt){}
}eg[E],EG[E];
void add(int u,int v,int w){
eg[++sum]=line(u,v,w,lt[u]); lt[u]=sum;
}
void dfs_1(int u){
dep[u]=dep[fa[u]]+; size[u]=; son[u]=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]) continue;
fa[v]=u;
dfs_1(v);
if (size[v]>size[son[u]]) son[u]=v;
size[u]+=size[v];
}
}
void dfs_2(int u,int tp){
top[u]=tp; w[u]=++cnt; rk[cnt]=u;
if (son[u]) dfs_2(son[u],tp);
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]||v==son[u]) continue;
dfs_2(v,v);
}
}
struct Segment_Tree{
int mx[V<<],lazy[V<<];
inline void pushup(int rt){
mx[rt]=max(mx[rt<<],mx[rt<<|]);
}
inline void pushdown(int rt){
if (lazy[rt]!=-INF){
lazy[rt<<]=max(lazy[rt<<],lazy[rt]);
lazy[rt<<|]=max(lazy[rt<<|],lazy[rt]);
mx[rt<<]=max(mx[rt<<],lazy[rt]);
mx[rt<<|]=max(mx[rt<<|],lazy[rt]);
lazy[rt]=-INF;
}
}
void build(int l,int r,int rt){
mx[rt]=-INF; lazy[rt]=-INF;
if (l==r) return;
int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt){
if (L<=l && r<=R){
lazy[rt]=max(val,lazy[rt]);
mx[rt]=max(mx[rt],val);
return;
}
pushdown(rt);
int m=(l+r)>>;
if (L <= m) update(L,R,val,lson);
if (m < R) update(L,R,val,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
return mx[rt];
}
pushdown(rt);
int m=(l+r)>>;
int res=-INF;
if (L <= m) res=max(res,query(L,R,lson));
if (m < R) res=max(res,query(L,R,rson));
return res;
}
}T1,T2;
int find(int x,int y){
int res=-INF;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,T1.query(w[top[x]],w[x],,n,));
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res=max(res,T1.query(w[x]+,w[y],,n,));
return res;
}
void change(int x,int y,int val){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
T2.update(w[top[x]],w[x],val,,n,);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
T2.update(w[x]+,w[y],val,,n,);
}
int main(){
int T,cas=;
scanf("%d",&T);
while (T--){
clr(lt,); sum=; cnt=; scanf("%d%d",&n,&m);
for (int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); add(v,u,w);
EG[i]=line(u,v,w);
}
for (int i=n;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
EG[i]=line(u,v,w);
}
dfs_1();
dfs_2(,);
T1.build(,n,);
T2.build(,n,);
for (int i=;i<n;i++){
if (dep[EG[i].u]>dep[EG[i].v]) swap(EG[i].u,EG[i].v);
T1.update(w[EG[i].v],w[EG[i].v],EG[i].w,,n,);
}
for (int i=n;i<=m;i++){
int tmp=find(EG[i].u,EG[i].v);
b[i]=tmp==-INF?-:EG[i].w-tmp;
change(EG[i].u,EG[i].v,-EG[i].w);
}
for (int i=;i<n;i++){
int tmp=T2.query(w[EG[i].v],w[EG[i].v],,n,);
a[i]=tmp==-INF?-:-tmp-EG[i].w;
}
LL res=;
for (int i=;i<n;i++) res=res+1ll*i*a[i]+1ll*i*i*-;
for (int i=n;i<=m;i++) res=res+1ll*i*-+1ll*i*i*b[i]; printf("Case %d: %lld\n",++cas,res );
}
}

UVALive 7338 (树链剖分+线段树)的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 &plus; 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】&lbrack;SDOI2011&rsqb;染色 树链剖分&plus;线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 &lpar;树链剖分&plus;线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 &lpar;树链剖分&plus;线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分&plus;线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分&plus;线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu&Tab;2450 Do use segment tree 树链剖分&plus;线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分&plus;线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通&plus;树链剖分&plus;线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243&lbrack;SDOI2011&rsqb;染色 树链剖分&plus;线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. hdu1255 矩阵的交 线段树&plus;扫描线

    /* 不是叶子节点 ,且cnt=1.注意这里,cnt=1确切的意义是什么, 应该是,可以确定,这个区间被完全覆盖了1次, 而有没有被完全覆盖两次或以上则不知道无法确定,那么怎么怎么办了, 只要加上t[ ...

  2. Ubuntu 14&period;04配置FTP服务器

    搭建: 1.sudo apt-get update                                        #更新软件 2.sudo apt-get install vsftpd ...

  3. SharePoint移动客户端--Rshare 中的Smart Cache

    Rshare中的Smart Cache 能好好的帮助那些移动客户,当网络信号不好或者没有wifi的时候,cache大有可为,只要你在上飞机执勤cache 了相关文档,你就可以在飞行模式下继续你的工作. ...

  4. Cocos2d-x课程大纲&sol;学习路线

    Cocos2d-x课程大纲/学习路线 这是什么? 这个一个Cocos2d-x技术路线的课程大纲/学习大纲. 你能用它做什么? 如果你是找工作的人, 利用本大纲, 你可以学习Cocos2d-x, 做一个 ...

  5. jquery mobile 复选框和单选框

    checkbox 和radio <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  6. hrbust1140 数字和问题

    题目: 定义一种操作为:已知一个数字,对其各位数字反复求和,直到剩下的数是一位数不能求和为止.例如:数字2345,第一次求和得到2 + 3 + 4 + 5 = 14,再对14的各位数字求和得到1 + ...

  7. vue里面引入jq的方法

    1:因为已经安装了vue脚手架,所以需要在webpack中全局引入jquery 打开package.json文件,在里面加入这行代码,jquery后面的是版本,根据你自己需求更改. dependenc ...

  8. HDU4112

    对于n*m*k的方块,用手掰成1**1的那么搜需要的步骤是固定的,为n*m*k-,如果用刀切,因为可以把多块叠在一起切,所以对于长度为n的,将他切成0,所需要的步骤数位k 对于n*m*k的方块,用手掰 ...

  9. Gym-101873D-Pants On Fire(闭包)

    原题链接:2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Pants On Fire Donald and M ...

  10. C&num; 压缩和解压文件(SharpZipLib)

    先从网上下载ICSharpCode.SharpZipLib.dll类库 将文件或文件夹压缩为zip,函数如下 /// <summary> /// 压缩文件 /// </summary ...