Codevs 2370 小机房的树

来源:互联网 发布:手机盯盘软件 编辑:程序博客网 时间:2024/05/18 03:40

Codevs 2370 小机房的树

裸lca。
关于如何转化图有多种方法,我记录了 每个节点的父亲, 到父亲的距离, 深度。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int MAXN = 50000 + 50;int n, tot = 0;int first[MAXN], nxt[MAXN << 1], dis[MAXN], deep[MAXN], fa[MAXN];bool dfsed[MAXN];struct edge{    int from, to, cost;}es[MAXN << 1];void build(int ff, int tt, int dd){    es[++tot] = (edge){ff,tt,dd};    nxt[tot] = first[ff];    first[ff] = tot;}void dfs(int x){    for(int i = first[x]; i != -1; i = nxt[i])    {        int v = es[i].to;        if(!dfsed[v])        {            dfsed[v] = 1;            dis[v] = es[i].cost;            deep[v] = deep[x] + 1;            fa[v] = x;            dfs(v);        }    }}int ask(int x, int y){    int ans = 0;    if(deep[x] > deep[y])        swap(x,y);    while(deep[y] != deep[x])    {        ans += dis[y];        y = fa[y];    }    while(x != y)    {        ans += dis[x];        ans += dis[y];        x = fa[x];        y = fa[y];    }    return ans;}int main(){    cin >> n;    memset(first,-1,sizeof(first));    for(int i = 1; i < n; i ++)    {        int f, t, d;        scanf("%d%d%d", &f, &t, &d);        build(f,t,d);        build(t,f,d);    }    deep[0] = 1;    dfsed[0] = 1;    fa[0] = 0;    dis[0] = 0x3f3f3f3f;    dfs(0);     int m;    cin >> m;    while(m --)    {        int x, y;        scanf("%d%d", &x, &y);        printf("%d\n",ask(x,y));    }    return 0;}
0 0
原创粉丝点击