zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    十道海量数据处理面试题与十个方法大总结
    TopK的一个简单实现
    Spark1.0.0 学习路线指导
    Apache Spark源码走读之1 -- Spark论文阅读笔记
    倾情大奉送--Spark入门实战系列
    分布式发布订阅消息系统 Kafka 架构设计
    hive入门学习线路指导
    (5.3.1)数据库迁移——数据库迁移解决孤立用户与权限问题
    Shell初学(八)linux下的ACL
    Shell初学(七)linux账户管理/群组管理
  • 原文地址:https://www.cnblogs.com/PCCCCC/p/14037857.html
Copyright © 2011-2022 走看看