hdu 2586 How far away? (LCA模板)

题意:

N个点,形成一棵树,边有长度。

M个询问,每个询问(a,b),询问a和b的距离

思路:

模板题,看代码。DFS预处理算出每个结点离根结点的距离。

注意:

qhead[maxn],而不是qhead[maxm]。

输出用%I64d,不要用%lld。

C++ RE后 尝试用 G++交。

代码:

struct node{
    int to,w,next,lca;
};
int const maxn = 40005;
int const maxm = 205;
int fa[maxn];
int head[maxn], qhead[maxn];
int cnt1,cnt2;
ll d[maxn];
ll res[maxm*2];
bool vis[maxn];

node edge[2*maxn];
node qedge[2*maxm];

int n,m;

int findFa(int x){
    return fa[x]==x?x:fa[x]=findFa(fa[x]);
}
inline void Addedge(int u,int v,int w){
    edge[++cnt1].w=w, edge[cnt1].to=v, edge[cnt1].next=head[u], head[u]=cnt1;
    edge[++cnt1].w=w, edge[cnt1].to=u, edge[cnt1].next=head[v], head[v]=cnt1;
}
inline void Addqedge(int u,int v){
    qedge[++cnt2].to=v, qedge[cnt2].next=qhead[u], qhead[u]=cnt2;
    qedge[++cnt2].to=u, qedge[cnt2].next=qhead[v], qhead[v]=cnt2;
}
void dfs(int u,int fa,ll w){
    d[u]=w;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa) continue;
        dfs(v,u,w+edge[i].w);
    }
}
void Tarjan_LCA(int u){
    fa[u]=u, vis[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].next){
        if(!vis[edge[i].to]){ //防止访问到父亲
            Tarjan_LCA(edge[i].to);
            fa[edge[i].to]=u;
        }
    }
    for(int i=qhead[u];i!=-1;i=qedge[i].next){
        if(vis[qedge[i].to]){
            qedge[i].lca=findFa(qedge[i].to);
            res[i]=d[u]+d[qedge[i].to]-2*d[qedge[i].lca];
        }
    }
}
void init(){
    rep(i,1,n) fa[i]=i;
    mem(head,-1);  mem(qhead,-1);  mem(vis,false);  mem(d,0);  mem(res,0);
    cnt1=cnt2=0;
}

int T,a,b,w;
int main(){
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        init();
        rep(i,1,n-1){
            scanf("%d%d%d",&a,&b,&w);;
            Addedge(a,b,w);
        }
        rep(i,1,m){
            scanf("%d%d",&a,&b);
            Addqedge(a,b);
        }
        dfs(1,-1,0);
        Tarjan_LCA(1);
        for(int i=1;i<=cnt2;i+=2){
            if(res[i])
                printf("%I64d\n",res[i]);
            else
                printf("%I64d\n",res[i+1]);
        }
    }
}
时间: 2024-10-10 00:01:41

hdu 2586 How far away? (LCA模板)的相关文章

HDU 5296 Annoying problem(LCA模板+树的dfs序心得)

Problem Description Coco has a tree, whose nodes are conveniently labeled by 1,2,-,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty. Now there are two kinds of operation: 1 x: If the node x is not in the set S, add n

HDU 2586 How far away LCA的离线算法 Tarjan

链接: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11204    Accepted Submission(s): 4079 Problem Description There are n houses in the village and some bidirectional roads connec

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B&quo

HDU 2586 How far away ? (LCA最近公共祖先)

题目地址:HDU 2586 LCA第一发. 纯模板题. 偷懒用的vector,结果一直爆栈.把G++改成C++就过了.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <se

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c

最近公共祖先(lca) hdu 2586

hdu 2586 How far away ? 题目大意:给定n-1条边构成一棵树,无向的:和m个询问,对于每一个询问按顺序回答. 结题思路:lca算法算出最近公共祖先,然后dis[u]+dis[v]-2*dis[father](father是u,v的最近公共祖先),小trick是在构造询问树的时候把权值设成询问对应的输入顺序 #include <iostream> #include <cstdio> #include <cstring> #include <al

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ

HDU 2586 LCA

LCA模板题. DFS记录好,到根结点的距离. #include <bits/stdc++.h> using namespace std; const int maxn = 40000+5; const int logmaxn = 20; struct Edge { int to,w; }; std::vector<Edge> G[maxn]; int f[maxn],dis[maxn],deep[maxn],p[maxn][20],n; struct LCA { int n; i

hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define maxn 10100 struct Edge { int u,v,w,next; }e[100100]; int n,m,c; int head[maxn],cnt; int fa[ma

HDU 2586 + HDU 4912 最近公共祖先

先给个LCA模板 HDU 1330(LCA模板) #include <cstdio> #include <cstring> #define N 40005 struct Edge{ int x,y,d,ne; }; Edge e[N*2],e2[N*2]; int be[N],be2[N],all,all2,n,m; bool vis[N]; int fa[N]; int ancestor[N][3]; int dis[N]; void add(int x, int y, int