初学并查集-1:家族

题目描述 Description

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

输入描述 Input Description

第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。 以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。 接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。

输出描述 Output Description

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

样例输入 Sample Input

6 5 3

1 2

1 5

3 4

5 2

1 3

1 4

2 3

5 6

样例输出 Sample Output

Yes

Yes

No

代码

var total,n,m:longint;
    father:array[1..10000000]of longint;
    used:array[1..10000000]of boolean;
    i,j,k,x,y:longint;
    yo:boolean;

function find(x:longint):longint;
         begin if father[x]=x
                  then exit(x);
               father[x]:=find(father[x]);
               exit(father[x]);
         end;

procedure union(a,b:longint);
          var i,j,k:longint;
          begin father[find(a)]:=find(father[b]);
          end;

begin yo:=false;
      fillchar(father,sizeof(father),0);
      fillchar(used,sizeof(used),true);
      readln(total,n,m);
      for i:=1 to total do
          father[i]:=i;
      for i:=1 to n do
          begin readln(x,y);
                if find(x)<>find(y)
                   then union(x,y);
          end;
      for i:=1 to m do
          begin readln(x,y);
                if find(x)=find(y)
                    then writeln(‘Yes‘)
                    else writeln(‘No‘);
          end;
end.
时间: 2024-10-13 13:22:11

初学并查集-1:家族的相关文章

初学并查集-2:最优布线问题

题目描述 Description 学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的.为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外一台计算机连接. 为了使得任意两台计算机之间都是连通的(不管是直接还是间接的),需要在若干台计算机之间用网线直接连接,现在想使得总的连接费用最省,让你编程计算这个最小的费用. 输入描述 Input Description 输入第一行为两个整数n,m(2<=n<=100000,2<=m<

初学并查集-3:浴火银河星际跳跃

题目描述 Description 小 K 又在玩浴火银河了...不过这次他的目的不是跑运输赚钱,而 是做任务赚钱. 他想知道关于一个任务的两个星系是否可以连通. 输入描述 Input Description 第一行,三个数,X,N,M X 表示出现的星系代号的最大值: N 表示有 N 个星际跳跃门; M 表示有 M 个任务. 接下来的 N 行描述每个星际跳跃门:每行为两个数字(星系代号), 星际跳跃门连通这两个星系(星际跳跃门是可以双向通行的) : 接下来的 M 行表示每个任务需要到达的星系,每

初学并查集-4:6个朋友

题目描述 Description 有这么一种说法:认识6个人,你就认识全世界的人. Aiden现在有一张关系图,上面记载了N个人之间相互认识的情况.Aiden想知道,他能否只认识6个人就能间接认识这N个人呢? 输入描述 Input Description 第一行,两个数N,M,表示有N个人,M对认识关系. 接下来的M行,每行两个数ai,bi,表示ai与bi相互认识. 不保证认识关系不出现重复,保证ai≠bi. N个人的编号为1...N. 输出描述 Output Description 若只认识6

codevs 1073 家族 并查集

没什么可以说的,并查集裸题,标签难度和实际不成正比啊,存个板子: 1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 23333 4 int n,m,p,fa[maxn]; 5 int getf(int); 6 int find(int,int); 7 int main() 8 { 9 scanf("%d %d %d",&n,&m,&p); 10 for(int i=1;i<

[tsA1491][2013中国国家集训队第二次作业]家族[并查集]

m方枚举,并查集O(1)维护,傻逼题,,被自己吓死搞成神题了... 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 struct tri { int x,y,z; bool operator<(const tri & temp)const { return z<temp.z; } }; 6 7 int n,m,k,Sum,Ans=0x7fffffff,a[1100],Size[1100],f[1100]; 8

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

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

CODEVS1073 家族 (并查集)

一道裸的并查集,练练手不错. program CODEVS1073; var i,j,m,n,q,x,y,k1,k2,z:longint; f:array[0..10000] of longint; function find(x:longint):longint; var fa:longint; begin while f[x]=x do exit(x); fa:=find(f[x]); f[x]:=fa; exit(fa); end; begin readln(n,m,q); for i:=

并查集 之 1073 家族

/* 并查集 */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm> 7 #include <string> 8 #include <locale> 9 #include <cmath> 10

BZOJ 3454 家族 并查集

题目大意:给定一张无向图,每个点有边权,给每个联通块大小一个喜爱度,求一个最小的区间,使保留这个区间内的所有边权的边时喜爱度之和最大 n<=1000,m<=5000 脑残没法治系列-- 如果暴力枚举区间并每次计算喜爱度,时间复杂度为O(nm^2),超时 固定一个左端点,将右端点右移,每次用并查集加边并维护喜爱度之和,时间复杂度O(m^2) 然后这题就做完了= = #include <cstdio> #include <cstring> #include <iost