社区讨论

萌新站外水题求助

灌水区参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lu70fjgp
此快照首次捕获于
2024/03/25 21:55
2 年前
此快照最后确认于
2024/03/25 22:38
2 年前
查看原帖
rt,不知道代码哪里写挂了
题目:
CPP
【问题描述】
有一颗树,求给定两节点的公共祖先,最后输出每个节点当做祖先的次数。

【输入格式】
输入文件包含多组测试数据。

对于每组测试数据的第一行为一个整数 n
�
(1≤n≤900
1
≤
�
≤
900
),表示结点个数;

接下来 n
�
 行,每行输入形式为 k:(t)k1,k2,…,kt
�
:
(
�
)
�
1
,
�
2
,
…
,
�
�
,其中:

第一个数字 k
�
,表示结点 k
�
;t
�
 表示 k
�
 的儿子个数,k1,k2,…,kt
�
1
,
�
2
,
…
,
�
�
 分别表示 k
�
 的儿子节点编号。

第 n+2
�
+
2
 行为一个整数表示询问最近公共祖先的结点对数

接下来若干行来描述询问的结点,用一对括号括起来。

【输出格式】
对于每组数据输出若干行,每行形式为 a:b
�
:
�
,表示结点 a
�
 做公共祖先有 b
�
 次,按照结点 a
�
 的顺序输出。

【样例输入15
5:(3) 1 4 2
1:(0)
4:(0)
2:(1) 3
3:(0)
6
(1,5)
(1,4)
(4,2)
(2,3)
(1,3)
(4,3)
【样例输出12:1
5:5
【样例1解释】


【数据范围及约定】
对于所有数据,1≤n≤900
1
≤
�
≤
900

Code:

CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 1e3 + 1, M = 2 * N;

int n, m;
int cnt[N];
int rt;
int p[N][20];
int h[N], e[M], ne[M], idx, d[N], fa[N];

inline void add(int a, int b)
{
    e[++idx] = b, ne[idx] = h[a], h[a] = idx ;
} 

inline void dfs(int x, int de)
{
    d[x] = de;
    for (int i = h[x]; i; i = ne[i])
    {
        int j = e[i];
        if (e[i] == fa[x]) continue;
        fa[j] = x;
        dfs(j, de + 1);
    }
}

inline void init()
{
    memset(p, -1, sizeof p);
    for (int i = 1; i <= n; i ++ ) p[i][0] = fa[i];
    for (int j = 1; (1 << j) <= n; j ++ )
      for (int i = 1; i <= n; i ++ )
        if (p[i][j - 1] != -1)
          p[i][j] = p[p[i][j - 1]][j - 1];
}

inline int lca(int a, int b)
{
    if (d[a] < d[b]) swap(a, b);
    int k;
    for (k = 0; (1 << (k + 1)) <= d[a]; k ++);
    for (int i = k; i >= 0; i --)
      if (d[a] - (1 << i) >= d[b])
        a = p[a][i];
    if (a == b) return a;
    for (int i = k; i >= 0; i --)
      if (p[a][i] != -1 && p[a][i] != p[b][i]) a = p[a][i], b = p[b][i];
    return p[a][0];
}

inline void solve()
{
    memset(fa, -1, sizeof fa);
    memset(h, -1, sizeof h);
    memset(cnt, 0, sizeof cnt);
    int npy = n;
    int k, t, y;
    while (npy -- )
    {
        scanf("%d%d", &k, &t);
        while (t -- )
        {
            scanf("%d", &y);
            add(k, y);
            add(y, k);
            fa[y] = k;
        }
    }
    for (int i = 1; i <= n; i ++ )
      if (fa[i] == -1)
      {
        rt = i;
        break;
      }
    dfs(rt, 1);
    init();
    int did;
    scanf("%d", &did);
    int xx, yy;
    while (did -- )
    {
        scanf("%d%d", &xx, &yy);
        cnt[lca(xx, yy)] ++ ;
    }
    for (int i = 1; i <= n; i ++ )
      if (cnt[i] != 0)
       printf("%d:%d\n", i, cnt[i]);        
}

int main()
{
    while (cin >> n)solve();
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...