• Codeforces Round #686 (Div. 3)


    Codeforces Round #686 (Div. 3)

    E. Number of Simple Paths

    思路:因为这个图的边和点的数量相等,所以保证图上只有一个简单环,我们找到这个环,把这个环上所有的边断掉,然后将这个环上所有点连向一个虚拟点 (0) ,以 (0) 为根(写的时候不用这么麻烦,这么说只是为了便于理解),统计父节点是 (0) 的所有子树的 (sz_1, sz_2, sz_3 .... sz_k) ,那么答案就是 ((sum_{i = 1}^k sum_{j = i + 1}^k sz_i * sz_j + n * (n - 1) / 2))

    我是用 (dfs) 树实现的,下面是代码

    #include <bits/stdc++.h>
    using namespace std;
    #define lc (rt << 1)
    #define rc ((rt << 1) | 1)
    #define fi first
    #define se second
    #define pb push_back
    #define pii pair<int, int>
    #define rep(i, l, r) for (int i = (l); i <= (r); ++i)
    #define per(i, r, l) for (int i = (r); i >= (l); --i)
    #define PE(i, u) for (int i = head[u]; i != -1; i = edge[i].next)
    typedef long long LL;
    const int maxn = 1e6 + 20;
    const int mod = 1e9 + 7;
    int n, m;
    struct Edge
    {
        int to, next;
    } edge[maxn * 2];
    int k, head[maxn];
    void add(int a, int b){
        edge[k].to = b;
        edge[k].next = head[a];
        head[a] = k++;
    }
    int d[maxn], dp[maxn], sz[maxn];
    LL ans = 0;
    int sum;
    void dfs(int u, int fa){
        sz[u] = 1;
        PE(i, u){
            int to = edge[i].to;
            if(to == fa) continue;
            if(!d[to]) {
                d[to] = d[u] + 1;
                dfs(to, u);
                dp[u] += dp[to];
                sz[u] += sz[to];
            } else if(d[to] > d[u]) dp[u]--;
            else if(d[to] < d[u]) {
                dp[u]++;
            }
        }
        if(dp[u]) {
            ans += 1LL * (sum - sz[u]) * sz[u];
            sum -= sz[u];
            sz[u] = 0;
        }
    }
    
    int main(int argc, char const *argv[])
    {
        int t;
        scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            sum = n;
            ans = 0;
            ans = 1LL * n * (n - 1) / 2;
            rep(i, 1, n){
                dp[i] = sz[i] = d[i] = 0;
                head[i] = -1;
            }
            rep(i, 1, n){
                int u, v;
                scanf("%d%d", &u, &v);
                add(u, v), add(v, u);
            }
            d[1] = 1;
            dfs(1, 0);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Nginx + FastCGI 程序(C/C++)搭建高性能web service的demo
    微服务架构
    异常点/离群点检测算法——LOF
    多边形区域填充算法--递归种子填充算法
    Java 关于容器集合等数据结构详情图解,一目了然
    平衡小车项目解读日志
    &lt;LeetCode OJ&gt; 101. Symmetric Tree
    【JVM】模板解释器--字节码的resolve过程
    hexo博客的相关配置
    【LeetCode】Find Minimum in Rotated Sorted Array 解题报告
  • 原文地址:https://www.cnblogs.com/PCCCCC/p/14037857.html
Copyright © 2020-2023  润新知