Traffic Network in Numazu

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;
}

原文地址:https://www.cnblogs.com/smallocean/p/9499248.html

时间: 2024-10-14 10:19:35

Traffic Network in Numazu的相关文章

H - Traffic Network in Numazu HDU - 6393(基环树)

Traffic Network in Numazu (HDU - 6393) 题意:给定一张\(n\)个点\(n\)条边的带权图.要求支持两种操作: \(0\ x\ y :\)修改第\(x\)条边的权值为\(y\). \(1\ x\ y :\)查询\((x,y)\)的最短路. 题解: \(n\)个点\(n\)条边,就是一颗基环树.我们可以拆掉基环树上的一条边,变为一棵树.那么两个点的最短路就是树上的距离和经过拆掉的边的距离,取最小值. 对于树上的距离,我们可以用线段树维护每个点到根节点的距离来求

杭电多校第七场 Traffic Network in Numazu

Problem Description 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

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

这道题相当于将这两题结合: http://poj.org/problem?id=2763 http://codeforces.com/gym/101808/problem/K 题意:有N各点N条边的带权无向图(相当于一棵树多了一条边),两种操作:修改一条边的权值:求两点间的最短路径. 分析:将任意一条边取出来,其余n-1条边可以结合LCA解最短路.询问时,比较通过取出的边和仅通过树上的边的路径的大小,最小值就是两点的最短路径. 树状数组差分维护点到根节点的距离,根据dfs序来记录需要维护的范围.

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

首先嘚瑟一下这场比赛的排名:59 (第一次看到这么多 √ emmmm) 好了进入正文QAQ ...这道题啊,思路很清晰啊. 首先你看到树上路径边权和,然后还带修改,不是显然可以想到 树剖+线段树 维护重链么? 然后你再看啊,这是一个连通图,然后有 n 个点 n 条边,于是很显然会有一个环(然后就构成了一个 仙人掌 ...不过我并不了解仙人掌) 然后你再看!这里只会有一个环,我们假设没有这个环,那么这就是一道 树剖 模板题,那么我们可不可以特殊地,让这个环当根,除这个环以外的其他节点来简单 树剖

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(两种),取最小值. 至于取出环上一条边,用并查集搞搞. #incl

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 traffic network including one or more turn restrictions, one or more U-turns and one or more P-turns using a Dijkstra algorithm. The method as sets a

2018 Multi-University Training Contest 7

1001:Age of Moyu 在SPFA的时候开一个set或map记录一下转移到他的边的种类,转移的时候尽量选和当前这条边种类一样的边转移,玄学复杂度,记得fread读入挂和register进行常数优化. 1 #include<bits/stdc++.h> 2 3 #define maxn 100000+5 4 #define maxm 200000+5 5 6 using namespace std; 7 8 struct Edge{ 9 int u,v,c,nxt; 10 }e[max

Network Load Balancing Technical Overview--reference

http://technet.microsoft.com/en-us/library/bb742455.aspx Abstract Network Load Balancing, a clustering technology included in the Microsoft Windows 2000 Advanced Server and Datacenter Server operating systems, enhances the scalability and availabilit

Exploring the Network

1. Examples of Today's Popular Communication Tools Instant Messaging(real-time communication)/Texting(Such as QQ, MSN) Weblogs (blogs)(individual):easy to update and edit Wikis: groups of people can edit and view together. Podcasting: an audio-based