HDU - 6393 Traffic Network in Numazu(树链剖分+基环树)
http://acm.hdu.edu.cn/showproblem.php?pid=6393
题意
给n个点和n条边的图,有两种操作,一种修改边权,另一种查询u到v的最短路。
分析
n个点和n条边,实际上是一棵树+一个环,如果仅仅是一棵树,那么这题就是树链剖分的模板题了。
对于环来说,可以考虑先把环中一条边提取出来,然后树链剖分,修改时用线段树,单点修改和区间求和。
查询时就考虑三种情况,u走树上到v,从u经过提取出来的边再到v(两种),取最小值。
至于取出环上一条边,用并查集搞搞。
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+; struct side {
int u,v,w;
int ne;
} s[maxn]; struct edge {
int l,r;
ll v;
} e[maxn<<]; int n,q;
int head[maxn],len;
int val[maxn],hold[maxn],pre[maxn];
int deep[maxn],fa[maxn],ve[maxn],son[maxn],top[maxn],p[maxn],fp[maxn],sz; void add(int u,int v,int w) {
s[len].u = u;
s[len].v = v;
s[len].w = w;
s[len].ne = head[u];
head[u] = len++;
} int find(int x) {
return pre[x] == x?x:pre[x] = find(pre[x]);
} void dfs1(int u,int p,int d) {
deep[u] = d;
fa[u] = p;
ve[u] = ;
son[u] = -;
for(int i = head[u]; i!= -; i = s[i].ne) {
if(s[i].v == p) continue;
val[s[i].v] = s[i].w; //把边权值赋给相连的点
hold[i>>] = s[i].v;//这条边的权值被哪个点掌握着
dfs1(s[i].v,u,d+);
ve[u]+= ve[s[i].v];
if(son[u] == -||ve[s[i].v]> ve[son[u]])
son[u] = s[i].v;
}
return ;
} void dfs2(int u,int sp) {
top[u] = sp;
p[u] = ++sz;
fp[p[u]] = u;
if(son[u] == -) return ;
dfs2(son[u],sp);
for(int i = head[u]; i!= -; i = s[i].ne) {
if(s[i].v == son[u]||s[i].v == fa[u]) continue;
dfs2(s[i].v,s[i].v);
}
return ;
} void build(int i,int l,int r) {
e[i].l = l;
e[i].r = r;
if(l == r) {
e[i].v = val[fp[l]];
return ;
} int mid = (l+r)>>;
build(i<<,l,mid);
build(i<<|,mid+,r);
e[i].v = e[i<<].v+e[i<<|].v;
} void modify(int i,int pos,int v) {
if(pos> e[i].r||pos< e[i].l) return ;
if(e[i].l == e[i].r) {
e[i].v = v;
return ;
}
modify(i<<,pos,v);
modify(i<<|,pos,v);
e[i].v = e[i<<].v+e[i<<|].v;
} ll query(int i,int l,int r) {
if(e[i].r< l||e[i].l> r) return ;
if(e[i].l>= l&&e[i].r<= r) return e[i].v;
return query(i<<,l,r)+query(i<<|,l,r);
} ll demand(int x,int y) {
int fx = top[x];
int fy = top[y];
ll ans = ;
while(fx!= fy) {
if(deep[fx]< deep[fy]) {
swap(fx,fy);
swap(x,y);
}
ans+= query(,p[fx],p[x]);
x = fa[fx];
fx = top[x];
}
if(x == y) return ans;
if(deep[x]> deep[y]) swap(x,y);
ans+= query(,p[son[x]],p[y]);
return ans;
} void init() {
sz = len = ;
mem(head,-);
for(int i = ; i<= n; i++) pre[i] = i;
} int main() {
int t;
cin>>t; while(t--) {
int su,sv,sc,ss;
scanf("%d %d",&n,&q);
init();
for(int i = ; i<= n; i++) {
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
int fx = find(u);
int fy = find(v); if(fx == fy) {
len+= ;
ss = i;
su = u;
sv = v;
sc = w;
continue;
} else
pre[fy] = fx;
add(u,v,w);
add(v,u,w);
} dfs1(,-,);
dfs2(,); build(,,n); while(q--) {
int o,x,y;
scanf("%d %d %d",&o,&x,&y);
if(o == ) {
x--;
if(x == ss) {
sc = y;
continue;
}
modify(,p[hold[x]],y);
} else {
ll ans;
ans = sc+min(demand(x,su)+demand(y,sv),demand(x,sv)+demand(y,su));
ans = min(ans,demand(x,y));
printf("%lld\n",ans);
}
}
}
return ;
}
HDU - 6393 Traffic Network in Numazu(树链剖分+基环树)的更多相关文章
- hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...
- HDU - 6393 Traffic Network in Numazu (基环树+树链剖分/LCA)
题意:给定一个带权边无向基环树,有两种操作,一种是改变某个边的权值,另一种是询问两点间的最短路径. 可以对环进行缩点,以环为根建立一棵新树,并记录与环相连的所有点和环上的哪个点相连,将路径分为环外和环 ...
- HDU - 6393 Traffic Network in Numazu (LCA+RMQ+树状数组)
这道题相当于将这两题结合: http://poj.org/problem?id=2763 http://codeforces.com/gym/101808/problem/K 题意:有N各点N条边的带 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- HDU 6162 Ch's gift(树链剖分+线段树)
题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 【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路径上的 ...
随机推荐
- npm config 删除变量
问题 安装npm时,使用npm config set 命令重新设置了变量,但是设置变量时少了个空格,设置错了.使用npm config ls -l 查看环境变量 添加错的这一个,应该如何删除? 解决 ...
- Hdoj 2602.Bone Collector 题解
Problem Description Many years ago , in Teddy's hometown there was a man who was called "Bone C ...
- 【BZOJ5287】[HNOI2018]毒瘤(动态规划,容斥)
[BZOJ5287][HNOI2018]毒瘤(动态规划,容斥) 题面 BZOJ 洛谷 题解 考场上想到的暴力做法是容斥: 因为\(m-n\le 10\),所以最多会多出来\(11\)条非树边. 如果就 ...
- 原生JS节点操作
获取子节点 1. children 不是标准的dom属性,但是几乎被所有浏览器支持.获取子元素的元素节点(只包括元素节点) 注意:在IE中,children包含注释节点. 2. childNodes ...
- 工作队列.py
#对列模式图Work Queue背后的主要思想是避免立即执行资源密集型任务的时,需要等待其他任务完成.所以我们把任务安排的晚一些,我们封装一个任务到消息中并把它发送到队列,一个进程运行在后端发送并最终 ...
- 【php】php从多个数组中取出最大的值
function _arr_max($arr = []){ if(func_num_args() > 1){ $result = []; foreach(func_get_args() as $ ...
- shell中定义变量用双引号和单引号以及不用引号的区别
1. 单引号 使用单引号的情况下,不管里面的是否有变量或者其他的表达是都是原样子输出 2. 双引号 如果其定义变量的时候使用双引号的话,则里面的变量或者函数会通过解析,解析完成后再输出内容,而不是把双 ...
- jsp (1)
一.jsp介绍: jsp是servlet的一种包装.是html+js+css+servlet. jsp文件无需配置,如果修改了jsp文件不需要reload应用. jsp访问方法:直接访问文件名.jsp ...
- angularjs优化方略
angular优化方略,闲的没事想重构的人来瞅瞅. 1.减少$watch 减少$watch,减少$watch,减少$watch.不仅仅是$watch监听,还有ng-model,别闲的没事就加个ng-m ...
- Docker安装及常用命令
修改机器名: [root@docker /]# hostnamectl set-hostname Docker 安装EPEL源: [root@docker /]# yum -y install epe ...