[CF1454E] Number of Simple Paths - 拓扑排序,基环树

Description

一颗基环树,请你计算出这张图中长度大于等于 1 的不同的简单路径的数量。

Solution

如果在环的一个子树内,那么只有一条路径

其它情况都有两条

所以做一个容斥即可

如何优雅地找一个环?

可以用类似拓扑排序的方法,用类似 BFS 的实现比较简单。每次将叶子添加到队列中,然后删掉与他相连的边,如果产生了新的叶子就加入到队列中。我们发现,最后所有的子树都会被删除,我们把它们的大小收缩的环上。

#include <bits/stdc++.h>
using namespace std;

#define int long long

void solve()
{
    int n;
    cin >> n;

    vector<set<int>> g(n + 2);
    vector<int> siz(n + 2, 1);

    for (int i = 1; i <= n; i++)
    {
        int u, v;
        cin >> u >> v;
        g[u].insert(v);
        g[v].insert(u);
    }

    queue<int> que;
    for (int i = 1; i <= n; i++)
        if (g[i].size() == 1)
            que.push(i);

    while (que.size())
    {
        int p = que.front();
        que.pop();
        int q = *g[p].begin();
        g[p].erase(q);
        g[q].erase(p);
        siz[q] += siz[p];
        siz[p] = 0;
        if (g[q].size() == 1)
            que.push(q);
    }

    int ans = 0;
    for (int i = 1; i <= n; i++)
        ans += siz[i] * (siz[i] - 1) / 2;
    ans = n * (n - 1) - ans;

    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    int t;
    cin >> t;
    while (t--)
        solve();
}

相关文章:

猜你喜欢
  • 2022-12-23
  • 2021-10-02
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-22
相关资源
相似解决方案