zoukankan      html  css  js  c++  java
  • Counting Stars hdu

    (idea)

    假设每条边包含在(t)个三元环中,那么这条边的贡献就是$t * (t - 1) / 2 $。将点分为两类 :

    • 度数(deg le sqrt(m))的点归为第一类点,然后枚举点数,(O(msqrt(m)))
    • 度数(deg > sqrt(m))的点归为第二类点,然后枚举边数,(O(msqrt(m)))

    因为度数超过(sqrt(m))的点至多有(sqrt(m))级别个,比如完全图(m = frac{n*(n - 1)}{2})。其实复杂度我也没分析得很清楚 orz

    (code)

    需要快速判读两点之间是否连有一条边。就哈希一条边,加到set里面。

    const int N = 100005;
    
    int n, m;
    int deg[N], pa[N];
    
    bool use[N];
    
    set<LL> s;
    vector<int> G[N];
    
    int main()
    {
        while(scanf("%d %d", &n, &m) != EOF) {
            mem(pa, 0);
            mem(deg, 0);
            mem(use, 0);
    
            s.clear();
            Rep(i, 1, n) G[i].clear();
    
            Rep(i, 1, m) {
                int u, v;
                sc(u), sc(v);
                deg[u]++;
                deg[v]++;
    
                G[u].pb(v);
                G[v].pb(u);
    
                s.insert(1ll * u * n + v);
                s.insert(1ll * v * n + u);
            }
    
            int limit = sqrt(1.0 * m);
    
            LL ans = 0;
            Rep(i, 1, n) {
                use[i] = 1;
                for (auto v : G[i]) pa[v] = i;
                for (auto v : G[i]) if (!use[v]) {
                    LL t = 0;
                    if (deg[v] <= limit) {
                        for (auto vv : G[v]) if (pa[vv] == i) t++;
                    }
                    else {
                        for (auto vv : G[i]) if (s.find(1ll * vv * n + v) != s.end()) t++;
                    }
                    ans += (t * (t - 1) / 2);
                }
            }
    
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    刷面经笔记2019.02.11
    刷面经笔记2019.02.10
    刷面经笔记2019.02.09
    刷面经笔记2019.02.07
    刷面经笔记2019.02.05
    刷面经笔记2019.01.31
    刷面经笔记2019.01.30
    刷面经笔记2019.01.28
    头条2020届实习生笔试题
    金s办公软件web前端笔试题
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9810243.html
Copyright © 2011-2022 走看看