HDU - 2586  (LCA模板题)

    xiaoxiao2023-10-11  117

    Tarjan:

    #include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; const int MAX = 40005; int n, m; struct Edge { int lca, v, to, next, st; } edge1[MAX * 2], edge2[MAX * 2]; int k = 0; int head1[MAX]; void add1(int a, int b, int c){ edge1[k].to = b; edge1[k].next = head1[a]; edge1[k].v = c; head1[a] = k++; } int head2[MAX]; void add2(int a, int b){ edge2[k].st = a; edge2[k].to = b; edge2[k].next = head2[a]; head2[a] = k++; } int par[MAX]; int Find(int x){ if(x == par[x]){ return x; } return par[x] = Find(par[x]); } void unit(int x, int y){ x = Find(x); y = Find(y); if(x == y){ return ; } par[y] = x; } int dis[MAX]; int vis[MAX]; void Tarjan(int rt){ vis[rt] = 1; for(int i = head1[rt]; i != -1; i = edge1[i].next){ int to = edge1[i].to; if(vis[to] == 0){ dis[to] = dis[rt] + edge1[i].v; Tarjan(to); unit(rt, to); } } for(int i = head2[rt]; i != -1; i = edge2[i].next){ int to = edge2[i].to; if(vis[to]){ edge2[i].lca = Find(to); edge2[i ^ 1].lca = Find(to); } } } int main() { int t; scanf("%d", &t); while(t--){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ head2[i] = head1[i] = -1; par[i] = i; vis[i] = 0; dis[i] = 0; } k = 0; for(int i = 1; i < n; i++){ int a, b, c; scanf("%d%d%d", &a, &b, &c); add1(a, b, c); add1(b, a, c); } k = 0; for(int i = 0; i < m; i++){ int a, b; scanf("%d%d", &a, &b); add2(a, b); add2(b, a); } Tarjan(1); for(int i = 0; i < k; i += 2){ int st = edge2[i].st; int to = edge2[i].to; int lca = edge2[i].lca; int ans = dis[st] + dis[to] - 2 * dis[lca]; printf("%d\n", ans); } } return 0; }

     

    倍增:

    #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <cmath> #include <map> using namespace std; const int MAX=4e4 + 50; int n, m; int depth[MAX]; int fa[MAX][60]; int in[MAX]; struct Edge { int to; int v; int next; } edge[2 * MAX]; int head[MAX]; int k = 0; void add(int a, int b, int c){ edge[k].to = b; edge[k].next = head[a]; edge[k].v = c; head[a] = k++; } int dis[MAX]; void dfs(int u, int pre, int d){ fa[u][0] = pre; depth[u] = d; for(int i = head[u]; i != -1; i = edge[i].next){ int to = edge[i].to; if(to != pre){ dis[to] = dis[u] + edge[i].v; dfs(to, u, d + 1); } } } void init(int root){ dfs(root, -1, 0); for(int j = 0; (1 << (j + 1)) < n; j++){ for(int i = 1; i <= n; i++){ if(fa[i][j] < 0){ fa[i][j + 1] = -1; } else{ fa[i][j + 1] = fa[fa[i][j]][j]; } } } } int LCA(int u, int v){ if(depth[u] > depth[v]){ swap(u, v); } int temp = depth[v] - depth[u]; for(int i = 0; (1 << i) <= temp; i++){ if((1 << i) & temp){ v = fa[v][i]; } } if(v == u){ return u; } int k = log2(n); for(int i = k; i >= 0; i--){ if(fa[u][i] != fa[v][i]){ u = fa[u][i]; v = fa[v][i]; } } return fa[u][0]; } int main() { int t; scanf("%d", &t); while(t--){ k = 0; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ in[i] = 0; fa[i][0] = 0; head[i] = -1; dis[i] = 0; } for(int i = 1; i < n; i++){ int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); add(b, a, c); } dfs(1, -1, 0); init(1); for(int i = 0; i < m; i++){ int a, b; scanf("%d%d", &a, &b); int lca = LCA(a, b); printf("%d\n", dis[a] + dis[b] - 2 * dis[lca]); } } return 0; };

    RMQ

    #include <iostream> #include <cstdio> #include <string.h> #include <vector> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <cmath> using namespace std; #define LL long long const int MAX = 4e4 + 50; struct Edge { int to; int next; int v; } edge[MAX * 2]; int n, tot, m; int id[MAX * 2], depth[2 * MAX], head[MAX * 2]; int ss[MAX], dp[2 * MAX][60], in[MAX]; int k = 0; void add(int a, int b, int c){ edge[k].to = b; edge[k].next = head[a]; edge[k].v = c; head[a] = k++; } int dis[MAX]; void dfs(int u, int pre, int d){ id[++tot] = u; ss[u] = tot; depth[tot] = d; for(int i = head[u]; i != -1; i = edge[i].next){ int to = edge[i].to; if(to == pre){ continue; } dis[to] = dis[u] + edge[i].v; dfs(to, u, d + 1); id[++tot] = u; depth[tot] = d; } } void ST(){ int nn = 2 * n - 1; int kk = log2(nn); for(int i = 1; i <= nn; i++){ dp[i][0] = i; } for(int j = 1; j <= kk; j++){ for(int i = 1; i + (1 << j) - 1 <= nn; i++){ int a = dp[i][j - 1]; int b = dp[i + (1 << (j - 1))][j - 1]; if(depth[a] < depth[b]){ dp[i][j] = a; } else{ dp[i][j] = b; } } } } int RMQ(int l, int r){ int kk = log2(r - l + 1); int a = dp[l][kk]; int b = dp[r - (1 << kk) + 1][kk]; if(depth[a] < depth[b]){ return a; } else{ return b; } } int LCA(int x, int y){ int l = ss[x]; int r = ss[y]; if(l > r){ swap(l, r); } return id[RMQ(l, r)]; } int main() { int t; scanf("%d", &t); while(t--){ scanf("%d%d", &n, &m); k = 0; tot = 0; for(int i = 1; i <= n; i++){ head[i] = -1; dis[i] = 0; } for(int i = 1; i < n; i++){ int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); add(b, a, c); } dfs(1, -1, 0); ST(); for(int i = 0; i < m; i++){ int a, b; scanf("%d%d", &a, &b); int lca = LCA(a, b); printf("%d\n", dis[a] + dis[b] - 2 * dis[lca]); } } return 0; }

     

    最新回复(0)