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;
    }
    
  • 相关阅读:
    Golang 函数
    Golang type
    Golang 分支控制和循环
    Golang 字符型
    Golang运算符
    final 和 static 的区别
    Golang标识符命名规则
    Golang值类型与引用类型
    Golang指针
    启动 jvm 参数小总结
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9810243.html
Copyright © 2011-2022 走看看