hdu1213 并查集板子

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1213/

并查集是一种支持合并与查找的数据结构,在森林中进行操作,加上路径压缩,合并和查找的时间复杂度几乎都是常数。并查集最基础的作用就是建立不同的点之间的所谓的“关系”,并且查询两者是否有关系。并查集的一个特点是向量型关系传递性,比如A->B B->C,则有A->C,是不是特别像向量之间的传递?在很多时候并查集的应用都涉及到了这个性质。并查集的代码可比线段树主席树友好一点orz hdu1213板题,代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define mp(a,b) make_pair((a),(b))
17 #define P pair<int,int>
18 #define dbg(args) cout<<#args<<":"<<args<<endl;
19 #define inf 0x3f3f3f3f
20 inline int read(){
21     int ans=0,w=1;
22     char ch=getchar();
23     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
24     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
25     return ans*w;
26 }
27 const int maxn=1e6+10;
28 int n,m,t;
29 int f[maxn];
30 set<int> s;
31 void init()
32 {
33     f(i,1,n)f[i]=i;
34     s.clear();
35 }
36 int find(int x)
37 {
38     if(x==f[x])return x;
39     f[x]=find(f[x]);//路径压缩,不然可能会构成一棵极度不平衡的树 
40     return f[x];
41  } 
42 void Union(int x,int y)
43 {
44     int fx=find(x);
45     int fy=find(y);
46     if(fx==fy)return ;//已经在同一棵树中
47     else 
48     {
49         f[fx]=fy;
50         //不在一棵树中就把这棵树的根结点连上b所在的树的根节点,实现合并 
51      } 
52 }
53 
54 int main()
55 {
56     //freopen("input.txt","r",stdin);
57     //freopen("output.txt","w",stdout);
58     std::ios::sync_with_stdio(false);
59     t=read();
60     int a,b;
61     while(t--)
62     {
63         n=read(),m=read();
64         init();
65         f(i,1,m)a=read(),b=read(),Union(a,b);
66         f(i,1,n)s.insert(find(i));//查看有多少个独立的树 
67         pf("%d\n",s.size());
68     }
69  } 

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12559969.html