并查集算法

来源:互联网 发布:python中正则表达式 编辑:程序博客网 时间:2024/05/16 04:57

并查集

      个人感觉就是回溯

      并查集=设置集合

      有时候深搜的题目也可以用并查集做,时间效率非常高

      但并查集的题目用深搜做100%超时


先贴上并查集的格式

function getfather(v:longint):longint; //查找v所在的集合的第一个家族的祖先begin  if tree[v]=v then exit(v)  else    begin      getfather:=getfather(tree[v]);      tree[v]:=getfather;    end;end;procedure union(x,y:longint); //把y加入到x的家族中去begin  x:=getfather(x);  y:=getfather(y);  tree[x]:=y;end;function judge(x,y:longint):boolean; //利用同一个家族祖先相同判断x,y是否在同一个家族begin  x:=getfather(x);  y:=getfather(y);  if tree[x]=y then exit(true)  else exit(false);end;


例题

图的连通分支

Time Limit:1000MS  Memory Limit:65536K

Description

输入一张顶点带权的无向图,分别计算含顶点数最多的一个连通分支和顶点的权之和最大的一个连通分支。

Input

第一行一个数n(顶点数,1<=n<=1000000) 
第二行有n个数,依次表示顶点1 ~ 顶点n上的权; 
第三行一个数e(边数,1<=e<=210000) 
以下e行,每行为有边连接的一对顶点。 

Output

两行,一行为含顶点数最多的一个连通分支的顶点数,一行为顶点的权之和最大的一个连通分支的值。

Sample Input

43 4 5 321 23 4

Sample Output

28

 这题从表面上看就是深搜找路

 但细看时间限制,1000MS,再看数据规模,

 深搜肯定得超时,所以果断选并查集做。

 大体的思路:

 1.读入点,for循环给集合初始化

 2.读入边,把边上两个点加入同一集合中

 3.for循环扫过去,得到答案


AC代码

var n,e,ans,max,maxweizhi:longint;  tree,treeable,mean,meanable:array[1..10000000]of longint;function getfather(v:longint):longint;begin  if tree[v]=v then exit(v)  else    begin      getfather:=getfather(tree[v]);      tree[v]:=getfather;    end;end;procedure marry(x,y:longint);begin  x:=getfather(x);  y:=getfather(y);  tree[x]:=y;end;function judge(x,y:longint):boolean;begin  x:=getfather(x);  y:=getfather(y);  if tree[x]=y then exit(true)  else exit(false);end;procedure init;var i,j,temp1,temp2:longint;begin  readln(n);  for i:=1 to n do tree[i]:=i;  for i:=1 to n do  read(mean[i]);  readln(e);  for i:=1 to e do  begin    readln(temp1,temp2);    marry(temp1,temp2);  end;  for i:=1 to n do getfather(i);  for i:=1 to n do  begin    inc(treeable[tree[i]]);    meanable[tree[i]]:=meanable[tree[i]]+ mean[i];  end;  max:=0;  for i:=1 to n do  if treeable[i]>max then  begin    max:=treeable[i];    maxweizhi:=i;  end;  writeln(max);  max:=0;  for i:=1 to n do  if meanable[i]>max then  begin    max:=meanable[i];  end;  writeln(max);end;begin  init;end.


  



0 0