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 ...
随机推荐
- redhat6.3安装MySQL-server-5.6.13-1.el6.x86_64.rpm
redhat6.3安装MySQL-server-5.6.13-1.el6.x86_64.rpm 首先下载下面三个文件: [plain] MySQL-client-5.6.13-1.el6.x ...
- KNN算法与Kd树
最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知 ...
- PHP 小方法之 计算两个时间戳之间相差的日时分秒
if(! function_exists ('timediff') ) { function timediff($begin_time,$end_time){ if($begin_time < ...
- for_each使用方法详解[转]
for_each使用方法详解[转] Abstract之前在(原創) 如何使用for_each() algorithm? (C/C++) (STL)曾經討論過for_each(),不過當時功力尚淺,只談 ...
- PHP中的变量详解
php变量通过名只能我们就知道首先变量,是在程序执行期间,可以变化的量. 1.那变量是干嘛的呢,用变量就可以来保存我们值,这就是变量,那么我们接着来看,知道了变量是什么,以及它能干什么,我们再来看一下 ...
- mybatis批量更新 UPDATE mysql
oracle和mysql数据库的批量update在mybatis中配置不太一样: oracle数据库: <update id="batchUpdate" parameterT ...
- js高级程序设计(七)函数表达式
定义函数的方式有两种:一种是函数声明,另一种就是函数表达式.函数声明的语法是这样的. function functionName(arg0, arg1, arg2) { //函数体 } Firefox ...
- postgres 查询数据库所有表名
select relname as TABLE_NAME ,col_description(c.oid, 0) as COMMENTS from pg_class cwhere relkind = ' ...
- 转-浅谈HTTP-GET 、 HTTP-POST 和SOAP
HTTP-GET 和 HTTP-POST HTTP-GET和HTTP-POST是标准协议,他们使用HTTP(超文本传输协议)谓词(谓词是指条件表达式的求值返回真或假的过程.)对参数金星编码并将参数作为 ...
- css\html布局及部分知识小分享~~~
近期发现和总结的知识跟大侠们分享,请大侠们多多评论指教一二? HTML 1.(1)body需设置页面默认字体大小 body{font-size:12px;} (2)IE6下png图片划过切换失效,建 ...