首页 > 其他分享 >P1989 无向图三元环计数 题解

P1989 无向图三元环计数 题解

时间:2023-09-28 18:13:24浏览次数:32  
标签:度数 int 题解 sqrt oud 无向 P1989

P1989 无向图三元环计数 题解

考虑对无向图的边定向:对于每一条无向边,度数小的点向度数大的点连边,如果读书相等则按编号大小确定。

这样枚举一个 \(u\),再枚举它的出点 \(v\),接着枚举 \(v\) 的出点 \(w\),如果存在一个 \(w\),\(u\) 向它连边,那么 \((u, v, w)\),就对应了原图中的一个三元环。

这样的时间复杂度是 \(O(m\sqrt m)\) 的,证明如下:

可以发现,总共的计算次数就是 \(\sum_{(u, v)\in E} oud_v\),其中 \(E\) 是有向图的边集,\(out_v\) 是 \(v\) 的出度。

分类讨论:

  1. 如果无向图中 \(v\) 的度数 \(\le \sqrt m\),显然有向图中 \(v\) 的度数一定不超过无向图的度数,则有 \(oud_v\le \sqrt m\)
  2. 如果无向图中 \(v\) 的度数 \(> \sqrt m\),那么有向图中,由于 \(v\) 只会向度数不小于自己的连边,所以 \(v\) 的出点 \(w\) 一定有 \(oud_w > \sqrt m\),已知总度数为 \(2m\),则度数 \(> \sqrt m\) 的点的数量只有大约 \(\dfrac{2m}{\sqrt m} = 2\sqrt m\) 个,因此 \(w\) 的个数一定在 \(O(\sqrt m)\) 的量级,所以 \(oud_v = O(\sqrt m)\)。

综上所述,\(oud_v = O(\sqrt m)\)。

所以 \(\sum_{(u, v)\in E} oud_v = O(m\sqrt m)\)。

实现不难,代码如下:

// Problem: P1989 无向图三元环计数
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2023-09-28 17:31:48

#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int N = 2e5 + 10;

vector<int> g[N];
int n, m, ind[N];
pair<int, int> e[N];
bool st[N];

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1, a, b; i <= m; i ++) {
        cin >> a >> b;
        ind[a] ++, ind[b] ++;
        e[i] = {a, b};
    }
    for(int i = 1; i <= m; i ++) {
        if(ind[e[i].first] < ind[e[i].second] || (ind[e[i].first] == ind[e[i].second] && e[i].first < e[i].second)) g[e[i].first].push_back(e[i].second);
        else g[e[i].second].push_back(e[i].first);
    }
    int ans = 0;
    for(int i = 1; i <= n; i ++) {
        for(auto v : g[i]) st[v] = 1;
        for(auto v : g[i]) {
            for(auto w : g[v])
                if(st[w]) ans ++;
        }
        for(auto v : g[i]) st[v] = 0;
    }
    cout << ans << '\n';

    return 0;
}

标签:度数,int,题解,sqrt,oud,无向,P1989
From: https://www.cnblogs.com/MoyouSayuki/p/17736295.html

相关文章

  • SOJ1835 题解
    题意给出一个\(1,\dots,n+1\)的排列\(v_{1},\dots,v_{n+1}\)与两组权值\(a_{1,\dots,n},b_{1,\dots,n}\)。满足\(v_{n+1}=n+1\)。构造一张\(n+1\)个点的有向图:对于\(i=1,\dots,n\),从\(i\)向\(i+1\)连一条权值为\(a_i\)的边;对于\(i=1,\dots,n\),找到最小的\(i......
  • LOJ 6479 [ICPC World Finals 2017] 小小水管工 Son of Pipe Stream 题解
    更好的阅读体验题意原题链接给出\(n\)个城市和\(m\)条双向管道,以及两个实数\(v\)和\(a\)。有两种液体,分别是水和Flubber(下面简写为W和F)。\(1\)号和\(2\)号城市分别生产Flubber和水,并通过管道流入\(3\)号城市。对于一条管道,其中可以同时存在两种液体,但是方向......
  • Jenkins问题解决_控制台输出:Windows下中文乱码,文本方式查看显示正常
    背景使用Git克隆代码时出现错误,控制台输出内容为中文乱码,文本方式查看显示正常Jenkins版本:2.423原因Jenkins内JAVA编码设置问题查看jenkins编码格式系统管理——>系统信息,查找sun.jnu.encoding字段。如果不是UTF-8,就可能导致中文支持有问题(GBK等支持度不够)。解决设......
  • 题解 [HEOI2016/TJOI2016] 排序
    题目链接看到这道题按照套路首先想到二分答案(即二分\(q\)位置上的数,记作\(mid\))。再按照套路将大于\(mid\)的数字设为\(1\),将等于\(mid\)的数设为\(2\),小于\(mid\)的数字设为\(0\)。那么对于区间\([l,r,0]\)操作,应该先讲\(0,1,2\)的数量找出来,然后按照从小到大......
  • 题解 CF1873H【Mad City】
    其他题解怎么又Tarjan又Dijkstra的,这是div4H的样子吗,来个简单好写的做法。题面里的人名太复杂了,本题解中称为警察和小偷。注意到,如果小偷成功到达了环上,那么一定不会被警察抓到。因为小偷知道警察下一步会走到哪里,他可以执行相同的操作(顺时针/逆时针/静止),使得他和警察之间......
  • [ARC124C] LCM of GCDs 题解
    题面给定\(N\)个正整数对\((a_i,b_i)\)和两个初始为空的集合\(S,T\),你可以选择将每个数对的两个元素划分到两个不同的集合中。求\[\max\operatorname{lcm}(\gcd\limits_{x\inS}x,\gcd\limits_{y\inT}y)\](\(1\leN\le50,1\lea_i,b_i\le10^9\))。题解首先,......
  • P4370 [Code+#4] 组合数问题2-题解-有关对数的小技巧
    20230927P4370[Code+#4]组合数问题2-solStatement传送门给你两个数\(n,k\),要求对于组合数\(C_{a}^{b}\)找到任何\(k\)个,让他们的和最大,且组合数各不相同,当且仅当\(a,b\)不完全相同时,组合数不同。Solution首先,很容易发现\(C_{n}^{m}\gtc_{n-1}^{m}\),所......
  • CF364D Ghd 题解
    CF364DGhd题解题目大意给定一个长度为\(n\)的序列,你需要从中选出一个元素个数不少于\(\left\lceil{\frac{n}{2}}\right\rceil\)的子序列,使得这个子序列中所有元素的\(\gcd\)最大。分析数据范围吓人。\(10^6\),但是根本想不到什么\(O(n\logn)\)或\(O(n)\)的算法......
  • [ARC125B] Squares 题解
    题意给定正整数\(N\),求满足如下条件的正整数对\((x,y)\)的数量:\(1\lex,y\leN\)\(x^2-y\)为完全平方数(\(0\)也是完全平方数)(\(1\leN\le10^{12}\))。题解因为\(x^2-y\)为完全平方数,设其为\(z^2\),那么有\[\begin{aligned}x^2-y=z^2\\\end{al......
  • [题解] Codeforces Round 900(Div.3) E~F
    CodeforcesRound900(Div.3)E~FE.Iva&Pav因为按位与的结果不会随着越多数字的增加而增加,因此我们可以利用这个性质二分出右端点,只需要一个可以查询区间的数据结构即可。或者是按位考虑第\(i\)个数字的第\(k\)位,后缀最近的\(0\)的位置,按位考虑也可以。但是这题使用二分......