7_6_A题 How far away?题解[hdu 2586](LCA Tarjan算法)

来源:互联网 发布:复杂网络同步 编辑:程序博客网 时间:2024/05/16 15:11

题目链接

题意

一个村子中的房子被一些长度不等的道路链接,保证无环(即构成一颗树),给出一些询问,询问两个房子之间的距离是多少。

思路

很明显的求最近公共祖先,使用Tarjan算法,在求LCA的过程中,记录节点到根的距离dis,然后对于每个询问,则 ans=dis[u]+dis[v]2dis[lca]

代码

#include <cstdio>#include <vector>#include <cstring>using namespace std;const int maxn = 4e4+5;const int maxq = 205;struct Edge{    int to,cost;    Edge(int t,int c):to(t),cost(c){};};struct Que{    int to,lca,idx;    Que(int t,int i):to(t),idx(i){};};vector <Edge> G[maxn];vector <Que> Ques[maxn];bool vis[maxn];int dis[maxn];int ans[maxq];int fa[maxn];void init(int n){    for(int i = 0 ; i <= n ; i ++){        G[i].clear();        Ques[i].clear();        fa[i] = i;    }    memset(dis,0,sizeof dis);    memset(ans,0,sizeof ans);    memset(vis,0,sizeof vis);}void addedge(int from, int to, int cost){    G[from].push_back(Edge(to,cost));    G[to].push_back(Edge(from,cost));}void addQue(int from, int to, int idx){    Ques[from].push_back(Que(to,idx));    Ques[to].push_back(Que(from,idx));}int Find(int x){    return fa[x] == x ? fa[x]:fa[x] = Find(fa[x]);}void Union(int x, int y){    int a = Find(x);    int b = Find(y);    if(a!=b) fa[b] = a;}void Tarjan(int cur){    vis[cur] = true;    for(int i = 0 ; i < G[cur].size(); i ++){        Edge& e = G[cur][i];        if(!vis[e.to]){            dis[e.to] = dis[cur] + e.cost;            Tarjan(e.to);            Union(cur,e.to);        }    }    for(int i = 0 ; i < Ques[cur].size() ; i ++){        Que & q = Ques[cur][i];        if(vis[q.to]){            q.lca = Find(q.to);            ans[q.idx] = dis[cur] + dis[q.to] - 2*dis[q.lca];        }    }}int main(){    int T;    scanf("%d", &T);    while(T --){        int n,q;        scanf("%d %d",&n,&q);        init(n);        for(int i = 1 ; i < n ; i ++){            int u,v,cost;            scanf("%d %d %d",&u,&v,&cost);            addedge(u,v,cost);        }        for(int i = 0 ; i < q ; i ++){            int u,v;            scanf("%d %d",&u,&v);            addQue(u,v,i);        }        Tarjan(1);        for(int i = 0 ; i < q; i ++){            printf("%d\n",ans[i]);        }    }    return 0;}
0 0
原创粉丝点击