C/C++ | 并查集:用于检查一个图上有没有环
没有环的过程分析:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define VERTICES 6
#define LINE 5
using namespace std; /*
parent:数组解决并查集合并问题
VERTICES:设定的顶点数
LINE:设定的边数
*/
void initialise(int *parent)
{
//用于parent数组的初始化
int i;
for(i=0;i<VERTICES;i++)
{
parent[i]=-1;
}
}
int find_root(int x,int parent[])
{
//用来查找根节点
int x_root = x;
while(parent[x_root] != -1)
{
x_root = parent[x_root];
}
return x_root; }
int union_vertices(int x,int y,int parent[])
{
//用于合并两个集合 。返回0:合并成功,返回1:合并失败
int x_root=find_root(x,parent);
int y_root=find_root(y,parent);
printf("x:当前数是%d,他的parent是:%d\n",x,x_root);
printf("y:当前数是%d,他的parent是:%d\n",y,y_root); if(x_root==y_root)
{
return 0;
}
else
{
parent[x_root]=y_root;//将x连到y上
return 1;
} }
int main()
{
int parent[VERTICES]={0};
initialise(parent);
int edges[LINE][2] = {
{0,1},{1,2},{1,3},
{2,4},{2,5}
};
for(int i=0;i<LINE;++i)
{
int x=edges[i][0];
int y=edges[i][1];
if(union_vertices(x,y,parent)==0)
{
printf("存在环");
exit(0);
}
}
printf("没有环");
return 0;
}
最后一次执行了“parent[x_root]=y_root;”,所以4的parent变成了5


存在环的过程分析:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define VERTICES 6
#define LINE 6
using namespace std; /*
parent:数组解决并查集合并问题
VERTICES:设定的顶点数
LINE:设定的边数
*/
void initialise(int *parent)
{
//用于parent数组的初始化
int i;
for(i=0;i<VERTICES;i++)
{
parent[i]=-1;
}
}
int find_root(int x,int parent[])
{
//用来查找根节点
int x_root = x;
while(parent[x_root] != -1)
{
x_root = parent[x_root];
}
return x_root; }
int union_vertices(int x,int y,int parent[])
{
//用于合并两个集合 。返回0:合并成功,返回1:合并失败
int x_root=find_root(x,parent);
int y_root=find_root(y,parent);
printf("x:当前数是%d,他的parent是:%d\n",x,x_root);
printf("y:当前数是%d,他的parent是:%d\n",y,y_root); if(x_root==y_root)
{
return 0;
}
else
{
parent[x_root]=y_root;//将x连到y上
return 1;
} }
int main()
{
int parent[VERTICES]={0};
initialise(parent);
int edges[LINE][2] = {
{0,1},{1,2},{1,3},
{2,4},{2,5},{3,4}
};
for(int i=0;i<LINE;++i)
{
int x=edges[i][0];
int y=edges[i][1];
if(union_vertices(x,y,parent)==0)
{
printf("存在环");
exit(0);
}
}
printf("没有环");
return 0;
}


最后一次没有执行“parent[x_root]=y_root;”
路径压缩:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define VERTICES 6
#define LINE 6
using namespace std; void initialise(int *parent,int rank[])
{ int i;
for(i=0;i<VERTICES;i++)
{
parent[i]=-1;
rank[i]=0;
}
}
int find_root(int x,int parent[])
{ int x_root = x;
while(parent[x_root] != -1)
{
x_root = parent[x_root];
}
return x_root; }
int union_vertices(int x,int y,int parent[],int rank[])
{ int x_root=find_root(x,parent);
int y_root=find_root(y,parent);
printf("x:当前数是%d,他的parent是:%d,他的rank是:%d\n",x,x_root,rank[x]);
printf("y:当前数是%d,他的parent是:%d,他的rank是:%d\n",y,y_root,rank[y]); if(x_root==y_root)
{
return 0;
}
else
{
if(rank[x_root] > rank[y_root])
{
parent[y_root]=x_root;
}
else if(rank[y_root]>rank[x_root])
{
parent[x_root]=y_root;
}
else
{
parent[x_root]=y_root;
rank[y_root]++;
}
return 1;
} }
int main()
{
int parent[VERTICES]={0};
int rank[VERTICES]={0};
initialise(parent,rank);
int edges[LINE][2] = {
{0,1},{1,2},{1,3},
{2,4},{2,5},{3,4}
};
for(int i=0;i<LINE;++i)
{
int x=edges[i][0];
int y=edges[i][1];
if(union_vertices(x,y,parent,rank)==0)
{
printf("存在环");
exit(0);
}
}
printf("没有环");
return 0;
}

C/C++ | 并查集:用于检查一个图上有没有环的更多相关文章
- 【并查集的另一个思考方向】POJ1456
POJ1456 这个题一看好像就是用贪心做啊,一个结构体,拍一下序,vis数组一遍遍扫荡,最后输出值,没错,贪心的确能做出来,而这类题目也能应用并查集,实现得思想也是贪心 #include <i ...
- poj 1182 食物链 并查集的又一个用法
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 41584 Accepted: 12090 Descripti ...
- 线段树 or 并查集 (多一个时间截点)
There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...
- D. Restructuring Company 并查集 + 维护一个区间技巧
http://codeforces.com/contest/566/problem/D D. Restructuring Company time limit per test 2 seconds m ...
- 【PAT甲级】1013 Battle Over Cities (25 分)(并查集,简单联通图)
题意: 输入三个整数N,M,K(N<=1000,第四个数据1e5<=M<=1e6).有1~N个城市,M条高速公路,K次询问,每次询问输入一个被敌军占领的城市,所有和该城市相连的高速公 ...
- LeetCode:并查集
并查集 这部分主要是学习了 labuladong 公众号中对于并查集的讲解,文章链接如下: Union-Find 并查集算法详解 Union-Find 算法怎么应用? 概述 并查集用于解决图论中「动态 ...
- 【POJ 1182 食物链】并查集
此题按照<挑战程序设计竞赛(第2版)>P89的解法,不容易想到,但想清楚了代码还是比较直观的. 并查集模板(包含了记录高度的rank数组和查询时状态压缩) *; int par[MAX_N ...
- codeforces 1023 D. Array Restoration 并查集
D. Array Restoration time limit per test 1 second memory limit per test 256 megabytes input standard ...
- POJ 1703 Find them, Catch them【种类/带权并查集+判断两元素是否在同一集合/不同集合/无法确定+类似食物链】
The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the ...
随机推荐
- JAVA在页面查看或下载服务器上的日志
1.配置 FileUtils类所需jar包的maven地址 <dependency> <groupId>commons-io</groupId> <artif ...
- SpringBoot错误经验
1.在application.properties 添加 debug=true,可以看见项目的执行流程有助于调bug 2.如果错误显示端口号被占用 cmd 步骤1 查看端口号应用情况:netstat ...
- node+express 发送get请求
var express = require('express') , app = express(); var querystring = require('querystring'); var ut ...
- UVa 11582 Colossal Fibonacci Numbers! 紫书
思路是按紫书上说的来. 参考了:https://blog.csdn.net/qwsin/article/details/51834161 的代码: #include <cstdio> # ...
- JAVA总结--集合
1.集合树状图 Collection:最基本的集合接口 ----List:有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问 ----ArrayList:异步 ----Linke ...
- [2019杭电多校第七场][hdu6656]Kejin Player
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意为从i级花费a元有p的概率升到i+1级,有1-p的概率降到x级(x<i),查询从L级升 ...
- Python 中的垃圾回收机制
GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在 ...
- 「Vue.js」Vue-Router + Webpack 路由懒加载实现
一.前言 当打包构建应用时,Javascript 包会变得非常大,影响页面加载.如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了.结合 Vue ...
- 《A chorus section detection method for musical audio signals and its application to a music listening section》
Abstract: 重复的副歌识别对音乐理解的计算模型(computational model)至关重要,应用层面有:音乐副歌识别预览,音乐检索等. 传统检测的难点:变调,起始点和结束点(both e ...
- Version Controlling with Git in Visual Studio Code and Azure DevOps
Overview Azure DevOps supports two types of version control, Git and Team Foundation Version Control ...