Traffic Network in Numazu

题目描述

Chika is elected mayor of Numazu. She needs to manage the traffic in this city. To manage the traffic is too hard for her. So she needs your help.

You are given the map of the city —— an undirected connected weighted graph with N nodes and N edges, and you have to finish Q missions. Each mission consists of 3 integers OP, X and Y.

When OP=0, you need to modify the weight of the Xth edge to Y.

When OP=1, you need to calculate the length of the shortest path from node X to node Y.

输入

The first line contains a single integer T, the number of test cases.

Each test case starts with a line containing two integers N and Q, the number of nodes (and edges) and the number of queries. (3≤N≤105)(1≤Q≤105)

Each of the following N lines contain the description of the edges. The ith line represents the ith edge, which contains 3 space-separated integers ui, vi, and wi. This means that there is an undirected edge between nodes ui and vi, with a weight of wi. (1≤ui,vi≤N)(1≤wi≤105)

Then Q lines follow, the ith line contains 3 integers OP, X and Y. The meaning has been described above.(0≤OP≤1)(1≤X≤105)(1≤Y≤105)

It is guaranteed that the graph contains no self loops or multiple edges.

输出

For each test case, and for each mission whose OP=1, print one line containing one integer, the length of the shortest path between X and Y.

样例输入

2

5 5

1 2 3

2 3 5

2 4 5

2 5 1

4 3 3

0 1 5

1 3 2

1 5 4

0 5 4

1 5 1

5 3

1 2 3

1 3 2

3 4 4

4 5 5

2 5 5

0 1 3

0 4 1

1 1 4

样例输出

5

6

6

6


基环树

N个点 但是有N条边 所以一定成环

简单地讲就是树上在加一条边

处理上分为树的处理和环的处理

参考 https://www.cnblogs.com/cly-none/p/9314812.html

本题先用并查集维护,找到那个环,将环中的任意一条边去掉 就成为树了。树可以用LCA+树状数组&树上差分处理,环就直接特判就好了。三条路,一个是只走树,一个是走到X再到Y再到v,一个是走到Y再到X再到u。

LCA

求最近公共祖先的模板

//+ DFS
void dfs(ll u,ll fa){//dfs建树
dep[u]=dep[fa]+1;
f[u][0]=fa;//初始化每个点的父节点
L[u]=++dfs_clock;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(v!=fa){
G[e[i].id]=v;
dfs(v,u);
}
}
R[u]=dfs_clock;
}
//+ 初始化
void rmq_init(int n)
{
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
if(f[i][j-1]) f[i][j] = f[f[i][j-1]][j-1];
}
//+ lca&rmq
int lca(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);//深度深的先处理
for(int i=19;i>=0;i--){
if(dep[u]>=dep[v]+(1<<i)){
u = f[u][i];
}
}
if(u==v){//跳到同一深度判断是否完成
return u;
}
for(int i=19;i>=0;i--){//一起跳
if(f[u][i]!=f[v][i]){
u=f[u][i];
v=f[v][i];
}
}
return f[u][0];
}
时间戳

dfs_clock 顾名思义就是遍历到该点的时间。

R[ ]记录着访问该点的时间点 L[ ]记录着该点最深的子节点的时间点。这样处理利于树状数组。

树状数组

修改时支持对该区间前缀和的修改

距离

前缀和已经维护好了 所以两点最短距离就是两点的前缀和的和减去2倍的父节点的前缀和

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
typedef long long ll;
struct Edge{
int v,next,id;
}e[maxn<<1];
int n,a[maxn],head[maxn],dep[maxn<<1],cnt,pos[maxn],dfs_seq[maxn<<1],dfn,f[maxn<<1][20];
int L[maxn],R[maxn],dfs_clock,G[maxn];
ll W[maxn],C[maxn];
inline void add(int u,int v,int id){
cnt++;
e[cnt].v=v;
e[cnt].next=head[u];
e[cnt].id=id;
head[u]=cnt;
}
inline int lowbit(int x){return (x)&(-x);}
void init(){
memset(head,0,sizeof(head));
memset(C,0,sizeof(C));
memset(dep,0,sizeof(dep));
cnt=0;
dfs_clock=0;
}
void dfs(ll u,ll fa){//dfs建树
dep[u]=dep[fa]+1;
f[u][0]=fa;//初始化每个点的父节点
L[u]=++dfs_clock;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(v!=fa){
G[e[i].id]=v;
dfs(v,u);
}
}
R[u]=dfs_clock;
}
void rmq_init(int n)
{
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
if(f[i][j-1]) f[i][j] = f[f[i][j-1]][j-1];
}
int lca(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);//深度深的先处理
for(int i=19;i>=0;i--){
if(dep[u]>=dep[v]+(1<<i)){
u = f[u][i];
}
}
if(u==v){//跳到同一深度判断是否完成
return u;
}
for(int i=19;i>=0;i--){//一起跳
if(f[u][i]!=f[v][i]){
u=f[u][i];
v=f[v][i];
}
}
return f[u][0];
}
inline void update(int i,ll x)
{
for(;i<=n;i+=lowbit(i)) C[i]+=x;
}
inline ll sum(int i)
{
ll s=0;
for(;i>0;i-=lowbit(i)) s+=C[i];
return s;
}
inline ll dist(int u,int v)
{
return sum(L[u])+sum(L[v])-2*sum(L[lca(u,v)]);
}
int main()
{
int i,u,v,k,q,T;
ll w;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&q);
init();
for(i=1;i<=n-1;++i){
scanf("%d%d%lld",&u,&v,&w);
add(u,v,i);
add(v,u,i);
W[i]=w;
}
dfs(1,0);
rmq_init(n);
int X,Y; ll Z;
scanf("%d%d%lld",&X,&Y,&Z);
W[n] = Z;
for(i=1;i<n;++i){
update(L[G[i]],W[i]);
update(R[G[i]]+1,-W[i]);
}
while(q--){
scanf("%d",&k);
if(k==0){
scanf("%d%lld",&u,&w);
if(u==n)
W[n] = w;
else{
update(L[G[u]],w-W[u]);
update(R[G[u]]+1,-w+W[u]);
W[u]=w;
}
}
else{
scanf("%d%d",&u,&v);
ll ans=dist(u,v);
ans=min(ans,dist(u,X)+dist(v,Y)+Z);
ans=min(ans,dist(u,Y)+dist(v,X)+Z);
printf("%lld\n",ans);
}
}
}
return 0;
}

Traffic Network in Numazu的更多相关文章

  1. HDU - 6393 Traffic Network in Numazu(树链剖分+基环树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6393 题意 给n个点和n条边的图,有两种操作,一种修改边权,另一种查询u到v的最短路. 分析 n个点和n条边,实 ...

  2. HDU contest808 ACM多校第7场 Problem - 1008: Traffic Network in Numazu

    首先嘚瑟一下这场比赛的排名:59 (第一次看到这么多 √ emmmm) 好了进入正文QAQ ...这道题啊,思路很清晰啊. 首先你看到树上路径边权和,然后还带修改,不是显然可以想到 树剖+线段树 维护 ...

  3. hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...

  4. HDU - 6393 Traffic Network in Numazu (LCA+RMQ+树状数组)

    这道题相当于将这两题结合: http://poj.org/problem?id=2763 http://codeforces.com/gym/101808/problem/K 题意:有N各点N条边的带 ...

  5. HDU - 6393 Traffic Network in Numazu (基环树+树链剖分/LCA)

    题意:给定一个带权边无向基环树,有两种操作,一种是改变某个边的权值,另一种是询问两点间的最短路径. 可以对环进行缩点,以环为根建立一棵新树,并记录与环相连的所有点和环上的哪个点相连,将路径分为环外和环 ...

  6. hdu6393 Traffic Network in Numazu 树链剖分

    题目传送门 题意:给出n个点n条边的无向带权图,再给出两种操作,操作1是将第x条边的边权修改为y,操作2是询问点x到点y的最短路径. 思路:如果是n个点n-1条边,题目就变成了树,修改边权和询问最短路 ...

  7. HDU-6393 Traffic Network in Numazu

    题意:给你一个n边n点的无向连通图,两个操作,操作一改变某个边的权值,操作二查询某两个点之间的路径长度. 题解:随便删掉环上一条边搞一棵树出来,因为两点间距离是两点各自到根的距离之和减去2*lca两点 ...

  8. hdu6393Traffic Network in Numazu【树状数组】【LCA】

    Traffic Network in Numazu Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (J ...

  9. Method for finding shortest path to destination in traffic network using Dijkstra algorithm or Floyd-warshall algorithm

    A method is presented for finding a shortest path from a starting place to a destination place in a ...

随机推荐

  1. CNN:扩张卷积输出分辨率计算

    扩张卷积(Dilated convolutions)是另一种卷积操作,也叫做空洞卷积(Atrous convolution).相比于普通的卷积,相同的卷积核,空洞卷积能够拥有更大的感受野. 相同的卷积 ...

  2. win10编译libpng

    libpng在windows的编译. ligpng的官网介绍如下: libpng is the official PNG reference library. It supports almost a ...

  3. VMware CentOS 设置IP地址

    VMware CentOS 设置IP地址 1. 设置虚拟机网络编辑器:参考:https://www.cnblogs.com/1285026182YUAN/p/10440443.html 2. Cent ...

  4. ftp限制

    /etc/hosts.deny /etc/vsftpd/user_list 从2.3.5之后,vsftpd增强了安全检查,如果用户被限定在了其主目录下,则该用户的主目录不能再具有写权限了!如果检查发现 ...

  5. 201771010123汪慧和《面向对象程序设计JAVA》第七周实验总结

    一.理论部分 1.继承 如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量,如果想要在子类里面做一系列事情,应该放在父类无参构造器里面,在java中,只允许单继 ...

  6. UOJ #2 【NOI2014】起床困难综合症

    这道题我们设两个bitset(N和Y) \(N_i = cal(i,0) , Y_i=cal(i,1)\) cal(i) 即第i位经过题目中的计算后所得出来的值 然后贪心.倒序循环i,考虑第i位如何决 ...

  7. 十二星座 英文名:Aries 金牛座 (4/21 - 5/20)的英文名: Taurus 双子座 (5/21 - 6/21)的英文名: Gemini 巨蟹座 (6/22 - 7/22)的英文名: Cancer 狮子座 (7/23 - 8/22)的英文名: Leo 处女座/室女座 (8/23 - 9/22)的英文名: Virgo 天秤座 (9/2

    十二星座的具体顺序是:白羊座(Aries).金牛座(Taurus).双子座(Gemini).巨蟹座(Cancer).狮子座(Leo).处女座(Virgo).天秤座(Libra).天蝎座(Scorpio ...

  8. Animate.css 一款强大的预设css3动画库

    Animate.css是一个有趣的,跨浏览器的css3动画库.很值得我们在项目中引用. 用法 1.首先引入animate css文件 <head> <link rel="s ...

  9. zabbix自定义邮件报警

    1.启动动作 2.设定发件人邮箱 进入QQ邮箱: 通过短信验证开启如下服务,并生成授权码: 3.配置收件人

  10. This inspection highlights chained comparisons that can be simplified.

    https://stackoverflow.com/questions/26502775/pycharm-simplify-chained-comparison In Python you can & ...