并查集 以及基础试题讲解

最简单而直观的假设是,对于连通的所有节点,我们可以认为它们属于一个组,因此不连通的节点必然就属于不同的组。我们需要首先判断输入的两个节点是否连通。如何判断呢?我们可以通过将所有的节点以整数表示,即对N个节点使用0到N-1的整数表示。而在处理输入的Pair之前,每个节点必然都是孤立的,即他们分属于不同的组,再按要求将点连接。

P1551 亲戚

题目背景

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。

题目描述

规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

输入输出格式

输入格式:

第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。

以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Mi和Mj具有亲戚关系。

接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。

输出格式:

P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。

输入输出样例

输入样例#1:

6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6

输出样例#1:

Yes
Yes
No
#include<iostream>
#include<cstdio>
#include<cmath>
#include<stdio.h>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[10000];
int find(int s)
{
    if(a[s]!=s)//如果father已经变化,
    a[s]=find(a[s]);//就搜到他的father
    return a[s];//把father值返回
}
void hebing(int x,int y)//如果father不同则合并
{
    a[y]=x;//father改掉
}
int main()
{

    int n,m,p;
    cin>>n>>m>>p;
    for(int i=1;i<=n;i++)
    {
        a[i]=i;//将所有的点的father先定义为自己
    }
    int x,y;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        int r1,r2;
        r1=find(x);//搜father
        r2=find(y);
        if(r1!=r2)//比较father
        hebing(r1,r2);//合并father
    }
    for(int i=1;i<=p;i++)
    {
        int j,k;
        cin>>j>>k;
        if(find(j)==find(k))//搜father
        cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}
时间: 2024-10-14 02:11:05

并查集 以及基础试题讲解的相关文章

并查集 - 图论基础

2017-07-25 22:18:16 writer:pprp 定义:(来源于搜狗百科)并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 作用:用来判断两个节点是否属于同一颗树: 操作:1,查找,Find    2,合并,Merge #include <iostream> using namespace std; int parent[1000]; int Find(int x) { if(parent[x] == x

并查集的基础

http://blog.csdn.net/dellaserss/article/details/7724401/ 史上最容易理解的解答!没有之一. 并查集能实现的功能:判断是否成环,计算共有多少个非连通图...待日后填坑 在最小生成树中应用 并查集最简代码! int f(int x){return x==pre[x]?x:pre[x]=f(pre[x]);} void mix(int a,int b) { int r=f(a),t=f(b); if(r!=t) pre[r]=t; }

杭电1213题解:一道最基础的并查集问题

Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want

并查集及应用

在信息学竞赛中,并查集是一种不可忽视的一部分内容,把最近几年的NOI和NOIP复赛题目大致浏览了一遍,发现有好几道应用并查集的题目,因此本文由浅入深的介绍并查集在编程中的巧妙应用. 什么是并查集?并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示.集就是让每个元素构成一个单元素的集合,并就是按一定顺序将属于同一组的元素所在的集合合并. 并查集的主要操作: 1.初始化:把每个点所在集合初始化为其自身: 2.查找:查找元素所在的

[NOIP摸你赛]Hzwer的陨石(带权并查集)

题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域的陨石全搬到了另外一些区域. 在ndsf愉快的搬运过程中,Hzwer想知道一些陨石的信息.对于Hzwer询问的每个陨石i,你必须告诉他,在当前这个时候,i号陨石在所在区域x.x区域共有的陨石数y.以及i号陨石被搬运的次数z. 输入描述: 输入的第一行是一个正整数T.表示有多少组输入数据. 接下来共有

带权并查集

似乎好些天没写文章了,感慨万千啊. 一如既往,先介绍一下题目的需求吧,如下: 题目简述:某人想编写一个字典,该字典中存在正反两种关系,并且这种关系具有某种规则下的传递性质,如下: A 与 B 同义, B 与 C 同义,则 A 与 C同义 : A 与 B 同义, B 与 C 反义,则 A 与 C反义 : A 与 B 反义, B 与 C 同义,则 A 与 C反义 : A 与 B 反义, B 与 C 反义,则 A 与 C同义 . 此人最初定义部分字符串的正反关系,要求以此为基础将所有给定字符串之间的关

POJ 1988 【并查集 妙用deep数组】

Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There

【codevs1073/P1551】家族/亲戚——并查集

题目链接:codevs,洛谷 这道题就是并查集的基础题,getf函数寻找该节点的祖先,要注意在查找的时候可以顺便把路上的节点的父节点也改为当前祖先(即路径压缩). 询问的时候不能因为两个点的父节点不同就说他们不是同一棵树上的,要一直找到他们的祖先再做比较. 具体实现细节看代码: #include<cstdio> #include<cstring> using namespace std; int f[5005]; int read() { int ans=0,f=1;char c=

读书笔记 之 数据结构(并查集详解)(POJ1703)

<ACM/ICPC算法训练教程>读书笔记-这一次补上并查集的部分.将对并查集的思想进行详细阐述,并附上本人AC掉POJ1703的Code. 在一些有N个元素的集合应用问题中,通常会将每个元素构成单元素集合,然后按照一定顺序将同属一组的集合合并,期间要反复查找每一个元素在哪个集合中.这类问题往往看似简单,但是数据量很大,因此容易造成TLE或MLE,也就是空间度和时间度极其复杂.因此在这里,我们引入一种抽象的特殊数据结构——并查集. 并查集:类似一个族谱,每个结点均有一个father[x]来表示x