图论三元环(并查集的高级应用)

题目描述

无聊的你回想起了A题的三角形,于是你想到了一个新的问题:

在一个连通图中,任何一条边都属于一个集合

如果两条边 a,b属于同一个集合当且仅当满足以下条件之一

  1. a,b 是某一个三角形的两条边

  2. 存在边 c ,使得 a,c 属于同一个集合且 b,c 属于同一个集合

那么请问,以下连通图的所有边是否都属于同一个集合?

输入描述:

第一行输入 T,表示 T 组样例

每组样例第一行输入两个正整数 n,m

接下来 m 行,第i行输入两个正整数 ai,bi​,表示第i条边连接 ai,bi​结点

数据保证图联通,且没有重边和自环

输出描述:

输出一个字符串表示答案

是输出 "Yes"

否输出 "No"

示例1

输入

复制代码
1
3 3
1 2
1 3
3 2

输出

复制代码
Yes

示例2

输入

复制代码
1
4 5
1 2
1 4
2 3
2 4
3 4

输出

复制代码
Yes

示例3

输入

复制代码
1
3 2
1 2
1 3

输出

复制代码
No

示例4

输入

复制代码
1
4 4
1 2
1 4
2 3
3 4

输出

复制代码
No

先放在这里

代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std; // 引入 std 命名空间

using i64 = long long;
using u64 = unsigned long long;

void solve() {
    int n, m;
    cin >> n >> m;
    vector<int> p(m + 1);

    auto find = [&] (auto self, int &x) -> int {
        if (x == p[x]) return x;
        return p[x] = self(self, p[x]);
    };

    auto merge = [&] (int &a, int &b) -> void {
        int fa = find(find, a), fb = find(find, b);
        if (fa != fb) {
            p[fb] = fa;
        }
    };

    vector<int> in(n + 1), u(m + 1), v(m + 1);

    for (int i = 1; i <= m; i++) {
        cin >> u[i] >> v[i];
        in[u[i]]++;
        in[v[i]]++;
        p[i] = i;
    }

    vector<vector<pair<int, int>>> e(n + 1);

    for (int i = 1; i <= m; i++) {
        if (in[u[i]] < in[v[i]] || (in[u[i]] == in[v[i]] && u[i] < v[i])) {
            e[v[i]].push_back({u[i], i});
        } else {
            e[u[i]].push_back({v[i], i});
        }
    }

    vector<pair<int, int>> vis(n + 1);

    for (int i = 1; i <= n; i++) {
        for (auto [x, j] : e[i]) vis[x] = {i, j};

        for (auto [x, j] : e[i]) {
            for (auto [y, k] : e[x]) {
                if (vis[y].first == i) {
                    merge(k, j);
                    merge(j, vis[y].second);
                }
            }
        } 
    }

    int ans = 0;
    for (int i = 1; i <= m; i++) {
        if (p[i] == i) ans++;
    }

    if (ans == 1) cout << "Yes\n";
    else cout << "No\n";
}

int main() {
    ios::sync_with_stdio(0);
    cout.tie(0);
    cin.tie(0);

    i64 t = 1; 
    cin >> t;
    while (t--) {
        solve();
    }
}
相关推荐
智驱力人工智能6 小时前
工厂智慧设备检测:多模态算法提升工业安全阈值
人工智能·算法·安全·边缘计算·智慧工厂·智能巡航·工厂设备检测
R-G-B8 小时前
【15】OpenCV C++实战篇——fitEllipse椭圆拟合、 Ellipse()画椭圆
c++·人工智能·opencv·fitellipse椭圆拟合·ellipse画椭圆·椭圆拟合·绘制椭圆
2501_924731479 小时前
城市路口识别准确率↑31%!陌讯时空建模算法在交通拥堵识别中的突破
人工智能·算法·目标检测·计算机视觉·目标跟踪
熬了夜的程序员9 小时前
【华为机试】208. 实现 Trie (前缀树)
数据结构·算法·华为od·华为
界面开发小八哥10 小时前
MFC扩展库BCGControlBar Pro v36.2:MSAA和CodedUI测试升级
c++·mfc·bcg·界面控件
小O的算法实验室11 小时前
2024年ESWA SCI1区TOP,自适应种群分配和变异选择差分进化算法iDE-APAMS,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
不吃洋葱.12 小时前
左子树之和
算法
金融小师妹13 小时前
基于AI量化模型的比特币周期重构:传统四年规律是否被算法因子打破?
大数据·人工智能·算法
极客BIM工作室13 小时前
C++ 限制类对象数量的技巧与实践
开发语言·javascript·c++
郝学胜-神的一滴14 小时前
Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形
c++·3d·unity·游戏引擎·godot·图形渲染·虚幻