Linxii's Blog
算法记录:图论Blur image

1.生成树#

1.1总体思考#

1.2 题目记录#

1.2.1 nowCoder 周赛140G 小红的生成树构造 链接#

  整场周赛都是赛后补做的,这个没写出来。然后去题解讨论看了文字题解,理解思路后,感觉不是很难,然后开始写代码,but在合并过程中这个”ABCD”的类别统计碰到了麻烦,想着用set来做统计,结果越写越麻烦,遂去看官方视频题解

  然后在这个统计每个连通块的类别的时候,苯环gg用了mask来进行统计,使用数字的二进制位来表示每个类别是否存在,这样就可以通过位运算来快速地统计和合并类别,非常巧妙。

  这个题目学到了二进制mask统计类别,总感觉似曾相识,但是就是自己做的时候想不到!!!

题解代码
struct DSU
{
    vector<int> f, siz, mask;
    DSU(int n)
    {
        init(n);
    }
    void init(int n)
    {
        f.resize(n);
        iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
        mask.assign(n, 0);
    }

    int find(int x)
    {
        if (x == f[x])
        {
            return x;
        }

        f[x] = find(f[x]);
        return f[x];
    }

    bool same(int x, int y)
    {
        return find(x) == find(y);
    }

    bool merge(int x, int y)
    {
        x = find(x);
        y = find(y);
        if (x == y)
        {
            return false;
        }

        siz[x] += siz[y];
        f[y] = x;
        mask[x] |= mask[y];
        return true;
    }

    int size(int x)
    {
        return siz[find(x)];
    }
};
void solve()
{
    int n, m;
    string s;
    cin >> n >> m >> s;
    DSU dsu(n);
    for (int i = 0; i < n; i++)
    {
        dsu.mask[i] = (1 << (s[i] - 'A'));
    }
    auto check = [&](char a, char b)
    {
        if (a > b)
        {
            swap(a, b);
        }

        return (abs(a - b) <= 1) && !(a == 'B' && b == 'C');
    };

    vector<pii> ans, ext;
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        u--, v--;
        if (check(s[u], s[v]))
        {
            if (!dsu.same(u, v))
            {
                dsu.merge(u, v);
                ans.push_back({u, v});
            }
        }
        else
        {
            ext.push_back({u, v});
        }
    }

    for (int i = 0; i < n; i++)
    {
        if (dsu.find(i) != i)
        {
            continue;
        }
        if (__builtin_popcount(dsu.mask[i]) != 2)
        {
            cout << "No" << endl;
            return;
        }
    }

    for (auto [u, v] : ext)
    {
        if (!dsu.same(u, v))
        {
            dsu.merge(u, v);
            ans.push_back({u, v});
        }
    }

    if (dsu.size(0) != n)
    {
        cout << "No" << endl;
        return;
    }
    else
    {
        cout << "Yes" << endl;

        for (auto [u, v] : ans)
        {
            cout << u + 1 << " " << v + 1 << endl;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    mainInit();
    i64 t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
cpp
算法记录:图论
https://tyuou2.github.io/blog/algorithm-2-graph/
Author 林夕夕
Published at April 24, 2026
Comment seems to stuck. Try to refresh?✨