并查集专栏

并查集 程序=数据结构+算法。
并查集是一种数据结构:针对若干个不相交集合,可以实现较快的两种操做:合并指定元素所属的集合、查找某元素在哪一个集合里。
 1 主要程序清单:int fa[maxn];
 2 ★ 初始化:for (i=1;i<=n;i++) fa[i]=i;//每一个元素单独成子集:根为序号
 3 ★ 查找元素x属于哪一个子集:
 4 int find(int x)   //查找元素x属于哪一个子集,同时进行“路径压缩”
 5 {    if (fa[x]!=x) fa[x]=find(fa[x]);  
 6     return fa[x]; //注意:若试题要求严格“父子”关系,则不能路径压缩
 7 }
 8 ★ 合并“元素x所在集合”和“元素y所在集合”:
 9 void un(int x,int y)    // union 是系统已经存在的子函数名,建议不要重名。
10 {    int rx,ry;
11     rx=find(x);ry=find(y);  // 查找各自所在的子集编号
12     if(rx!=ry) fa[rx]=ry;   //若编号不一样,则不要同一集合,进行“合并”。
13 }

亲戚relation算法

Time Limit:5000MS  Memory Limit:65536K数据结构

Description 函数

  或许你并不知道,你的某个朋友是你的亲戚。他多是你的曾祖父的外公的女婿的外甥女的表姐的孙子。若是能获得完整的家谱,判断两我的是不是亲戚应该是可行的,但若是两我的的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及。在这种状况下,最好的帮手是计算机。
  为了将问题简化,你将获得一些亲戚关系的信息,如同Xuebin和Grant是亲戚,Grant和Tension是亲戚等,从这些信息中,你能够推出xuebin和Tension是亲戚。请写一个程序,对于咱们的关于亲戚关系的提问,以最快的速度给出答案。
spa

Input code

输入由两部分组成:
第一部分以N、M开始。N为问题涉及到的人的个数(1≤N≤20 000)。这些人的编号为一、二、三、…、N。
 下面有M行(1≤M≤1 000 000),每行有两个数ai、bi,表示已知ai和bi是亲戚。
第二部分以Q开始。如下Q行有Q个询问(1≤Q≤1 000 000),每行为ci、di,表示询问ci和di是否为亲戚。
blog

Output ip

对于每一个询问ci、di,输出一行:若ci和di为亲戚,则输出Yes,不然输出No。
ci

Sample Inputit

10 7
2 4
5 7
1 3
8 9
1 2
5 6
2 3
3
3 4
7 10
8 9

Sample Outputio

Yes
No
Yes

〖实例 亲戚〗 // 裸“并查集”
 1 #include<cstdio>
 2 #define MAXN 1000000 //数据大,快速读入
 3 using namespace std;
 4 int fa[MAXN]={0};
 5 int find(int x)   // 查找x所属集合编号
 6 {    if (fa[x]!=x) fa[x]=find(fa[x]);
 7     return fa[x];
 8 }
 9 void un(int x,int y)   //并集
10 {    int rx,ry;
11     rx=find(x);ry=find(y);  
12     if(rx!=ry) fa[rx]=ry;  
13 }
14 int main(){
15     int n,m,i,x,y,t;
16     scanf("%d%d",&n,&m);
17     for (i=1;i<=n;i++)fa[i]=i; //并查集初始化
18     for (i=1;i<=m;i++)
19     {    scanf("%d%d",&x,&y);  un(x,y);  }
20     scanf("%d",&t);
21     for (i=1;i<=t;i++)    {
22         scanf("%d%d",&x,&y);
23         if (find(x)==find(y)) printf("Yes\n");
24         else printf("No\n");
25     }
26 return 0; } 
27  
相关文章
相关标签/搜索