HDU - 6393 Traffic Network in Numazu (基环树+树链剖分/LCA)
题意:给定一个带权边无向基环树,有两种操作,一种是改变某个边的权值,另一种是询问两点间的最短路径。
可以对环进行缩点,以环为根建立一棵新树,并记录与环相连的所有点和环上的哪个点相连,将路径分为环外和环内的两类进行处理。环外的路径可以用树剖+树状数组维护,环内的路径复制一倍,用另一个树状数组维护。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+;
int hd[N],n,m,ne,sta[N],tp,vis[N],id[N],anc[N],lid[N],nl;
int fa[N],son[N],siz[N],dep[N],top[N],bg[N],ed[N],rnk[N],tot;
struct E2 {int u,v,c;} e2[N];
struct E {int v,c,nxt;} e[N<<];
struct BIT {
ll c[N<<];
int n;
int lb(int x) {return x&-x;}
void add(int u,int x) {for(; u<=n; u+=lb(u))c[u]+=x;}
ll get(int u) {ll ret=; for(; u; u-=lb(u))ret+=c[u]; return ret;}
ll sum(int l,int r) {return get(r)-get(l-);}
void init(int _n) {memset(c,,sizeof c),n=_n;}
} tr1,tr2;
void addedge(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
bool isloop(int u) {return id[u]==n+;}
bool dfs_loop(int u,int f) {
if(vis[u]) {
while(!lid[u]) {
int v=sta[tp--];
id[v]=n+,lid[v]=++nl;
}
return ;
}
vis[u]=,sta[++tp]=u;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==f)continue;
if(dfs_loop(v,u))return ;
}
tp--;
return ;
}
void dfs_anc(int u,int f,int a) {
anc[u]=a;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==f||isloop(v))continue;
dfs_anc(v,u,a);
}
}
void dfs_chain_1(int u,int f,int d) {
fa[u]=f,son[u]=,siz[u]=,dep[u]=d;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||isloop(v))continue;
dfs_chain_1(v,u,d+),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs_chain_2(int u,int tp) {
top[u]=tp,bg[u]=++tot,rnk[bg[u]]=u;
if(son[u])dfs_chain_2(son[u],tp);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||v==son[u]||isloop(v))continue;
dfs_chain_2(v,v);
}
ed[u]=tot;
}
void upd(int u,int v,int x) {
if(isloop(u)&&isloop(v)) {
int l=lid[u],r=lid[v];
if(l>r)swap(l,r);
if(r-l!=)swap(l,r);
tr2.add(r,-tr2.sum(r,r)),tr2.add(r+nl,-tr2.sum(r+nl,r+nl));
tr2.add(r,x),tr2.add(r+nl,x);
} else {
int l=bg[id[u]],r=bg[id[v]];
if(l>r)swap(l,r);
tr1.add(r,-tr1.sum(r,r)),tr1.add(r,x);
}
}
ll qry_loop(int u,int v) {
int l=lid[u],r=lid[v];
if(l>r)swap(l,r);
return min(tr2.sum(l+,r),tr2.sum(r+,l+nl));
}
ll qry_tree(int u,int v) {
int ancu=anc[u],ancv=anc[v];
u=id[u],v=id[v];
ll ret=;
for(; top[u]!=top[v]; u=fa[top[u]]) {
if(dep[top[u]]<dep[top[v]])swap(u,v);
ret+=tr1.sum(bg[top[u]],bg[u]);
}
if(dep[u]<dep[v])swap(u,v);
ret+=tr1.sum(bg[v]+,bg[u]);
ret+=qry_loop(ancu,ancv);
return ret;
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
memset(hd,-,sizeof hd),ne=tp=nl=tot=;
memset(vis,,sizeof vis);
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i) {
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c),addedge(v,u,c);
e2[i]= {u,v,c};
}
for(int i=; i<=n; ++i)id[i]=i;
dfs_loop(,),id[n+]=n+;
for(int u=; u<=n; ++u)if(isloop(u))dfs_anc(u,,u);
for(int u=; u<=n; ++u)if(isloop(u)) {
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(!isloop(v))addedge(n+,v,e[i].c);
}
}
dfs_chain_1(n+,,),dfs_chain_2(n+,n+);
tr1.init(tot),tr2.init(nl*);
for(int i=; i<=n; ++i)upd(e2[i].u,e2[i].v,e2[i].c);
while(m--) {
int f,a,b;
scanf("%d%d%d",&f,&a,&b);
if(f==)upd(e2[a].u,e2[a].v,b);
else printf("%lld\n",qry_tree(a,b));
}
}
return ;
}
也可以LCA+差分维护每个点到根节点的距离,复杂度少了个log(但实际速度差不了多少)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+;
int hd[N],n,m,ne,sta[N],tp,vis[N],id[N],anc[N],lid[N],nl;
int fa[N],son[N],siz[N],dep[N],top[N],bg[N],ed[N],rnk[N],tot;
struct E2 {int u,v,c;} e2[N];
struct E {int v,c,nxt;} e[N<<];
struct BIT {
ll c[N<<];
int n;
int lb(int x) {return x&-x;}
void add(int u,int x) {for(; u<=n; u+=lb(u))c[u]+=x;}
ll get(int u) {ll ret=; for(; u; u-=lb(u))ret+=c[u]; return ret;}
ll sum(int l,int r) {return get(r)-get(l-);}
void init(int _n) {memset(c,,sizeof c),n=_n;}
} tr1,tr2;
void addedge(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
bool isloop(int u) {return id[u]==n+;}
bool dfs_loop(int u,int f) {
if(vis[u]) {
while(!lid[u]) {
int v=sta[tp--];
id[v]=n+,lid[v]=++nl;
}
return ;
}
vis[u]=,sta[++tp]=u;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==f)continue;
if(dfs_loop(v,u))return ;
}
tp--;
return ;
}
void dfs_anc(int u,int f,int a) {
anc[u]=a;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==f||isloop(v))continue;
dfs_anc(v,u,a);
}
}
void dfs_chain_1(int u,int f,int d) {
fa[u]=f,son[u]=,siz[u]=,dep[u]=d;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||isloop(v))continue;
dfs_chain_1(v,u,d+),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs_chain_2(int u,int tp) {
top[u]=tp,bg[u]=++tot,rnk[bg[u]]=u;
if(son[u])dfs_chain_2(son[u],tp);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||v==son[u]||isloop(v))continue;
dfs_chain_2(v,v);
}
ed[u]=tot;
}
void upd(int u,int v,int x) {
if(isloop(u)&&isloop(v)) {
int l=lid[u],r=lid[v];
if(l>r)swap(l,r);
if(r-l!=)swap(l,r);
tr2.add(r,x),tr2.add(r+nl,x);
} else {
u=id[u],v=id[v];
if(fa[u]==v)swap(u,v);
tr1.add(bg[v],x),tr1.add(ed[v]+,-x);
}
}
ll qry_loop(int u,int v) {
int l=lid[u],r=lid[v];
if(l>r)swap(l,r);
return min(tr2.sum(l+,r),tr2.sum(r+,l+nl));
}
ll qry_tree(int u,int v) {
int ancu=anc[u],ancv=anc[v];
u=id[u],v=id[v];
ll ret=tr1.get(bg[u])+tr1.get(bg[v]);
for(; top[u]!=top[v]; u=fa[top[u]])
if(dep[top[u]]<dep[top[v]])swap(u,v);
if(dep[u]<dep[v])swap(u,v);
ret-=*tr1.get(bg[v]);
ret+=qry_loop(ancu,ancv);
return ret;
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
memset(hd,-,sizeof hd),ne=tp=nl=tot=;
memset(vis,,sizeof vis);
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i) {
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c),addedge(v,u,c);
e2[i]= {u,v,c};
}
for(int i=; i<=n; ++i)id[i]=i;
dfs_loop(,),id[n+]=n+;
for(int u=; u<=n; ++u)if(isloop(u))dfs_anc(u,,u);
for(int u=; u<=n; ++u)if(isloop(u)) {
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(!isloop(v))addedge(n+,v,e[i].c);
}
}
dfs_chain_1(n+,,),dfs_chain_2(n+,n+);
tr1.init(tot),tr2.init(nl*);
for(int i=; i<=n; ++i)upd(e2[i].u,e2[i].v,e2[i].c);
while(m--) {
int f,a,b;
scanf("%d%d%d",&f,&a,&b);
if(f==)upd(e2[a].u,e2[a].v,b-e2[a].c),e2[a].c=b;
else printf("%lld\n",qry_tree(a,b));
}
}
return ;
}
HDU - 6393 Traffic Network in Numazu (基环树+树链剖分/LCA)的更多相关文章
- 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(树链剖分+基环树)
http://acm.hdu.edu.cn/showproblem.php?pid=6393 题意 给n个点和n条边的图,有两种操作,一种修改边权,另一种查询u到v的最短路. 分析 n个点和n条边,实 ...
- HDU - 6393 Traffic Network in Numazu (LCA+RMQ+树状数组)
这道题相当于将这两题结合: http://poj.org/problem?id=2763 http://codeforces.com/gym/101808/problem/K 题意:有N各点N条边的带 ...
- Traffic Network in Numazu
Traffic Network in Numazu 题目描述 Chika is elected mayor of Numazu. She needs to manage the traffic in ...
- hdu6393 Traffic Network in Numazu 树链剖分
题目传送门 题意:给出n个点n条边的无向带权图,再给出两种操作,操作1是将第x条边的边权修改为y,操作2是询问点x到点y的最短路径. 思路:如果是n个点n-1条边,题目就变成了树,修改边权和询问最短路 ...
- 【BZOJ 2791】 2791: [Poi2012]Rendezvous (环套树、树链剖分LCA)
2791: [Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组询问由两 ...
- CodeForces 916E Jamie and Tree(树链剖分+LCA)
To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...
- NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
原文链接https://www.cnblogs.com/zhouzhendong/p/9275606.html 题目传送门 - 洛谷P1600 题目传送门 - LOJ#2359 题目传送门 - Vij ...
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
随机推荐
- HBITMAP与BITMAP 的区别
HBITMAP 是句柄: BITMAP 是实例: typedef struct tagBITMAP { LONG bmType; ...
- 例子 使用sqlite3 数据库建立数据方式
#!/usr/bin/env python#coding:utf-8import sqlite3#建立一个数据库cx = sqlite3.connect("E:/test.db") ...
- EMA指数平滑移动平均
英文参考:http://www.incrediblecharts.com/indicators/exponential_moving_average.php Exponential moving av ...
- 闲记Windows 取证艺术
是不是很好奇,别人能够在你电脑上查看你运行程序历史,文档使用痕迹,浏览器浏览历史种种历史痕迹,没错,通过简单的系统了解以及配合相对应的工具,这一切就是这么的简单,看起来很高大上的操作,其实是 ...
- 【转载】softmax的性质及其实现
原文地址:https://segmentfault.com/a/1190000010039529?utm_source=tag-newest softmax函数将任意n维的实值向量转换为取值范围在(0 ...
- 【VS开发】【电子电路技术】VPX技术介绍
VPX技术介绍 杨跃江 2009-12-18 杨跃江 13902479857 中科祥云(深圳)信息产业有限公司 1VPX 技术 新型VPX(VITA 46)标准是自从VME引入后的25年来,对于VME ...
- 【Linux开发】linux设备驱动归纳总结(四):4.单处理器下的竞态和并发
linux设备驱动归纳总结(四):4.单处理器下的竞态和并发 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- H.Holy Grail ( floyd )(The Preliminary Contest for ICPC Asia Nanjing 2019)
题意: 给出一个有向图,再给出6条原来不存在的路径,让你在这6条路径上添加一个最小的数,使图不存在负环. 思路: 直接6遍 floyd 输出就行了. #include <bits/stdc++. ...
- JS中的继承(下)
JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
- Zabbix 监控常见服务
监控Apache性能 1.客户端编译安装Apache服务,并在编译选项中开启监控页面功能. [root@localhost ~]# yum install -y gcc openssl openssl ...