题目链接: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 ",s.size()); 68 } 69 }