刷题之前来几套LCA的末班

对于题目

HDU 2586 How far away

2份在线模板第一份倍增,倍增还是比较好理解的

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 40040;
const int MAXM = MAXN * 2;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int u,v,w;
    int next;
}edge[MAXM];
int head[MAXN],tot;
int N;

void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int dep[MAXN],fa[MAXN],cost[MAXN];
int sumcost[MAXN][20],anc[MAXN][20];
bool vis[MAXN];

void bfs(int root)
{
    memset(vis,false,sizeof(vis));
    queue<int>q;
    q.push(root);
    vis[root] = true;
    fa[root] = -1;
    dep[root] = 0;
    cost[root] = 0;
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        for (int i = head[u] ; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v;
            if (vis[v]) continue;
            dep[v] = dep[u] + 1;
            cost[v] = edge[i].w;
            fa[v] = u;
            vis[v] = true;
            q.push(v);
        }
    }
}

void preprocess()
{
    memset(sumcost,0,sizeof(sumcost));
    for (int i = 1 ; i <= N ; i++)
    {
        anc[i][0] = fa[i];
        sumcost[i][0] = cost[i];
        for (int j = 1 ; (1 << j) <= N ; j++) anc[i][j] = -1;
    }
    for (int j = 1 ; (1 << j) <= N ; j++)
    {
        for (int i = 1 ; i <= N ; i++)
        {
            if (anc[i][j - 1] != -1)
            {
                int a = anc[i][j - 1];
                anc[i][j] = anc[a][j - 1];
                sumcost[i][j] = sumcost[i][j - 1] + sumcost[a][j - 1];
            }
        }
    }
}


int query(int p,int q)
{
    int tmp,log;
    if (dep[p] < dep[q]) swap(p,q);
    for (log = 1 ; (1 << log) <= dep[p] ; log++); log--;
    int ans = 0;
    for (int i = log ; i >= 0 ; i--)
    {
        if (dep[p] - (1 << i) >= dep[q])
        {
            ans += sumcost[p][i];
            p = anc[p][i];
        }
    }
    if (p == q) return ans;
    for (int i = log ; i >= 0 ; i--)
    {
        if (anc[p][i] != -1 && anc[p][i] != anc[q][i])
        {
            ans += sumcost[p][i]; p = anc[p][i];
            ans += sumcost[q][i]; q = anc[q][i];
        }
    }
    ans += cost[p];
    ans += cost[q];
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        init();
        int Q;
        scanf("%d%d",&N,&Q);
        for (int i = 0 ; i < N - 1 ; i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w);
            add_edge(v,u,w);
        }
        bfs(1);
        //printf("%d %d %d %d\n",fa[2],fa[3],cost[2],cost[3]);
        preprocess();
        //printf("%d %d %d %d\n",anc[2][0],anc[3][0],sumcost[2][0],sumcost[3][0]);
        while(Q--)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            printf("%d\n",query(u,v));
        }
    }
    return 0;
}
View Code

相关文章:

  • 2021-12-12
  • 2022-12-23
  • 2021-10-24
  • 2021-09-25
  • 2021-11-26
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-04-10
  • 2022-12-23
  • 2022-01-21
  • 2021-10-11
  • 2021-09-09
  • 2021-12-10
  • 2021-08-31
相关资源
相似解决方案