标签:style blog color io os ar for sp div
就两个操作:
一个find(int a,int b); 在find的同时进行路径压缩
一个unio(int a,int b); 里面调用find,看祖先是否相同;
模板Code:
hiho:1066,无间道并查集
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <math.h> 5 #include <string.h> 6 #include <vector> 7 #include <queue> 8 using namespace std; 9 10 #define MAXN 1000010 11 int m,k,fa[MAXN]; 12 13 int f[MAXN]; 14 void init(int n)//初始化 15 { 16 for(int i=0;i<=n;i++) 17 { 18 fa[i]=i; 19 f[i]=0; 20 } 21 } 22 //查找的时候,进行路径压缩fa[x]=find(fa[x]) 23 //把查找路径上的结点都指向根结点,减少树的高度。 24 int find(int x) 25 { 26 if(x != fa[x]) 27 fa[x]=find(fa[x]);//路径压缩 28 return fa[x]; 29 } 30 //合并 , 在同一个集合,返回0;不在则进行合并,同时返回1 31 void unio(int x,int y) 32 { 33 int fx=find(x),fy=find(y); 34 if(fx==fy) return ; 35 if(f[fy]<f[fx])//将rank值小的合并到大的中 36 fa[fy]=fx; 37 else 38 { 39 fa[fx]=fy; 40 if(f[fx]==f[fy]) 41 f[fy]++; 42 } 43 } 44 int look(int x,int y) //判断是否在同一个集合中 ,是返回0;不是返回1 45 { 46 int fx=find(x),fy=find(y); 47 //printf("fx: %d fy:%d\n",fx,fy); 48 49 if(fx==fy) return 0; 50 else return 1; 51 } 52 char name[100010][20]; 53 char name1[20],name2[20]; 54 int len ; 55 int findName(char str[20]){ //姓名数组从坐标1开始 56 for(int i=1;i<=len;i++){ 57 if(strcmp(str,name[i])==0) return i+1; 58 } 59 strcpy(name[len],str); //复制姓名 60 len++; 61 62 return len; 63 } 64 65 int main(){ 66 int n;len = 1; 67 scanf("%d",&n); 68 init(n); //记得初始化fa数组!!!! 69 for(int i=0;i<n;i++){ 70 int t;scanf("%d",&t); 71 scanf("%s %s",name1,name2); 72 int a = findName(name1)-1; 73 int b = findName(name2)-1; 74 if(t==0){ // 为0的时候进行进行并集操作 75 //printf("合并: %d %d\n",a,b); 76 unio(a,b); 77 }else{// 进行查询操作 78 //printf("查找: %d %d\n",a,b); 79 if(look(a,b)==0){ 80 printf("yes\n"); 81 }else{ 82 printf("no\n"); 83 } 84 } 85 } 86 87 return 0; 88 }
这里是加了一个字符串处理的操作。
标签:style blog color io os ar for sp div
原文地址:http://www.cnblogs.com/songacm/p/4034914.html