UVALive 7338 (树链剖分+线段树)
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 (树链剖分+线段树)的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- [Scrapy] Mac安装Scrapy
Mac安装Scrapy Mac版本 10.11 El Captain. 前一段想在Mac上用Scrapy,各种问题.有一个不错的工具:Anaconda. 安装Anaconda 下载地址 我还是下pyt ...
- js产生随机数并加入数组
<!doctype html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- code异常处理
private void copyPrivateRawResuorceToPubliclyAccessibleFile() { InputStream inputStream = null; File ...
- shell学习笔记1
知识点1.修改输出的颜色 echo -e "\e[1;31m This is red text \e[0m" 其中,\e[1;31m 表示将输出显示为红色: \e[0m 标识将颜色 ...
- Scrum Meeting 4-20151204
任务安排 姓名 今日任务 明日任务 困难 董元财 学习上拉加入新的listview 无 胡亚坤 设计优化聊天页面 无 刘猛 请假(参加编译测试,提前准备) 无 马汉虎 请假(参加编译测试,提前准备) ...
- socket初级使用(客户端)
在国庆这段时间里用零星的一些时间看了一下socket的学习资料,由于笔者偏向学习实用方面的内容,因此此篇文章涉及理论知识较少,主要是以实现思路(怎么做)为主,但在实现之前还是需要了解一些基础的理论知识 ...
- magic_quotes_gpc
ini里面有这个magic_quotes_gpc设置,是为了防止忘记处理而和mysql有冲突,引起mysql的风险,于是,认为的加上\slash,但是我们在Php中获得值的时候,需要判断如果这个值为1 ...
- python之map、filter、reduce、lambda函数 转
python之map.filter.reduce.lambda函数 转 http://www.cnblogs.com/kaituorensheng/p/5300340.html 阅读目录 map ...
- Android 之 Activity的生命周期
- Android开发--LinearLayout的应用
1.简介 LinearLayout为安卓三大常用布局中的线性布局.其中,线性布局又分为水平线性布局和垂直线性布局.视图如下所示: