经典算法 判断一个图中是否有环

判断一个图中是否有环

问题描述

给一个以0 0结尾的整数对列表,除0 0外的每两个整数表示一条连接了这两个节点的边。假设节点编号不超过100000大于0。你只要判断由这些节点和边构成的图中是否存在环。存在输出YES,不存在输出NO。

输入样例1

in 复制代码
6 8  5 3  5 2  6 4 5 6  0 0

输出样例1

in 复制代码
NO

输入样例2

in 复制代码
8 1  7 3  6 2  8 9  7 5 7 4  7 8  7 6  0 0

输出样例2

in 复制代码
NO

输入样例3

in 复制代码
3 8  6 8  6 4 5 3  5 6  5 2  0 0

输出样例3

in 复制代码
YES

输入样例4

in 复制代码
1 2 3 4 0 0

输出样例4

in 复制代码
NO

输入样例5

空图没有环

cpp 复制代码
0 0

输出样例5

in 复制代码
NO

c++代码

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

int a, b;
int arr[100001];
bool key = false;

int myfind(int x) {
    int root = x;
    while(root != arr[root]) root = arr[root];
    int i = x, j;
    while(i != root) {
        j = arr[i];
        arr[i] = root;
        i = j;
    }
    return root;
}

void mymerge(int x, int y) {
    x = myfind(x), y = myfind(y);
    if (x != y) arr[y] = arr[x];
}

int main() {
    for (int i = 1; i <= 100000; i++) arr[i] = i;
    while(true) {
        scanf("%d %d", &a, &b);
        if (a == 0 && b == 0) break;
        if (key) continue;
        int x = myfind(a), y = myfind(b);
        if (x == y) key = true;
        else mymerge(a, b);
    }
    if (key) printf("YES");
    else printf("NO");
    return 0;
}//by wqs

算法解析

给每个点一个初始的编号,并初始化所有节点的父亲为本身。每新加入一条边就把边相连的两个集合合并到一起,如果边相连的集合原本就是同一个,说明已经成环。

相关推荐
白杨尚青10 小时前
C++入门篇(十):string(上)——认识string:构造与三大遍历(一条龙讲透operator[]、迭代器、auto、范围for)
java·开发语言·c++·笔记·stl
FlightYe10 小时前
视界原理之2D视频(二):视频文件里有什么
android·linux·网络·c++·ffmpeg·音视频·aac
可乐鸡翅yeah_10 小时前
hls.js 切换多个视频源,新手开发常见踩坑
开发语言·前端·javascript·ios·ffmpeg·音视频·safari
Tanshu_API君10 小时前
API 聚合平台选型指南:从参数拆解到生产落地的十个评估维度
开发语言·api
Chen—LSN10 小时前
C语言——⽂件操作(1)
c语言·开发语言·c++·经验分享·笔记·算法·链表
狗凯之家源码网10 小时前
PHP 开源 IM 即时通讯系统效果实测与功能展示
开发语言·开源·php
anew___10 小时前
《从零手写操作系统 (11):文件系统初探——initrd与VFS抽象层》
java·javascript·算法
天天向上29110 小时前
Spring AI 实战:14 个踩坑记录,其中一个让我的测试全绿但产品是坏的
java·开源
正在走向自律11 小时前
从只写接口到独立交付前后端,飞算JavaAI能给Java后端工程师多少溢价?
java·springboot·ai编程·全栈开发·java求职·飞算javaai·金九银十
辛苦才能11 小时前
C++ map/set 深度解析:从关联式容器的本质到 operator[] 的三重身份
开发语言·c++