acm 第六天:树

#include<cstdio>
#include<cstring>
using namespace std;
int head[10200];
int headcnt;
int res,t;
struct list{
    int u,v,w;
    int next;
}edge[10200];
void add(int u,int v,int w){
    edge[headcnt].u=u;
    edge[headcnt].v=v;
    edge[headcnt].w=w;
    edge[headcnt].next=head[u];
    head[u]=headcnt++;
    edge[headcnt].u=v;
    edge[headcnt].v=u;
    edge[headcnt].w=w;
    edge[headcnt].next=head[v];
    head[v]=headcnt++;
}
void dfs(int u,int v,int w)
{
    if(res<w)
        res=w,t=u;
    for(int i=head[u];i!=-1;i=edge[i].next)
        if(edge[i].v!=v)
            dfs(edge[i].v,u,w+edge[i].w);
}
int main()
{
    headcnt=0;
    memset(head,-1,sizeof(head));
    int u,v,w;
    while(scanf("%d%d%d",&u,&v,&w)!=EOF)
    {
        add(u,v,w);
        //add(v,u,w);
    }
    res=0;
    dfs(1,0,0);
    dfs(t,0,0);
    printf("%d\n",res);
    return 0;
}
void dfs(int u,int p)  // u 为当前结点,p为当前结点的父结点
{
    for(auto v:g[u])  //枚举子结点 邻接表存图(vector g[size])
    {
        if(v==p) continue; //避免访问父结点
        dfs(v,u);
    }
}

void bfs(int root)
{
    q.push(root); //根结点入队
    while(q.size())  //q.size() 返回队列大小(O(1))
    {
        int u = q.front(); //取队首元素
        q.pop(); //队首出队
        vis[u] = true; //访问标记
        for(auto v:g[u])  // 枚举子结点
        {
            if(vis[v]) continue; //避免访问父结点
            q.push(v); // 子结点入队
        }
    }
}

#include<bits/stdc++.h>
using namespace std;
const int SIZE = 50010;
int f[SIZE][20], d[SIZE], dist[SIZE];
int ver[2 * SIZE], Next[2 * SIZE], edge[2 * SIZE], head[SIZE];
int T, n, m, tot, t;
queue<int> q;
void add(int x, int y, int z)
{
    ver[++tot] = y;
    edge[tot] = z;
    Next[tot] = head[x];
    head[x] = tot;
}
// 预处理
void bfs()
{
    q.push(1);
    d[1] = 1;
    while (q.size())
    {
        int x = q.front();
        q.pop();
        for (int i = head[x]; i; i = Next[i])
        {
            int y = ver[i];
            if (d[y]) continue;
            d[y] = d[x] + 1;
            dist[y] = dist[x] + edge[i];
            f[y][0] = x;
            for (int j = 1; j <= t; j++)
                f[y][j] = f[f[y][j - 1]][j - 1];
            q.push(y);
        }
    }
}
// 回答一个询问
int lca(int x, int y)
{
    if (d[x] > d[y]) swap(x, y);
    for (int i = t; i >= 0; i--)
        if (d[f[y][i]] >= d[x]) y = f[y][i];
    if (x == y) return x;
    for (int i = t; i >= 0; i--)
        if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    return f[x][0];
}
int main()
{
    cin >> T;
    while (T--)
    {
        cin >> n >> m;
        t = (int)(log(n) / log(2)) + 1;
// 清空
        for (int i = 1; i <= n; i++) head[i] = d[i] = 0;
        tot = 0;
// 读入一棵树
        for (int i = 1; i < n; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            add(x, y, z), add(y, x, z);
        }
        bfs();
// 回答问题
        for (int i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            printf("%d\n", dist[x]+dist[y]-2*dist[lca(x, y)]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42748371/article/details/86535738