赞
踩
1、 用二维数组来构建一个树,第一维为结点下标,第二维为子节点,单个二维数组的值为子节点下标。构建字典树用于查询和插入。
- #include<bits/stdc++.h>
- //835 存储查询字符串
- using namespace std;
- const int N=1e5+10;
- int son[N][26],cnt[N],idx;
- char str[N];
- //下标是0的节点既是根节点,又是空节点
- //son数组第一维为父节点的下标,第二维度为某一个儿子的字母,其值为其这个儿子的下标
- void insert(char str[])
- {
- int p=0;//都是从0号位置开始
- for(int i=0;str[i];i++)
- {
- int u=str[i]-'a';//儿子映射为数字
- if(!son[p][u]) son[p][u]=++idx;
- //为父节点添加儿子
- p=son[p][u];
- //更新父节点
- }
- cnt[p]++;//最后一个p即为一个字符串的尾结点,记录这个结点出现的次数
- }
-
- int query(char str[])
- {
- int p=0;
- for(int i=0;str[i];i++)
- {
- int u=str[i]-'a';
- if(!son[p][u])return 0;
- p=son[p][u];
- }
- return cnt[p];
- }
- int main()
- {
- int n;
- scanf("%d",&n);
- for(int i=0;i<n;i++)
- {
- char op[2];
- scanf("%s%s",op,str);
- //两个字符串输入的时候中间要有空格
- if(*op=='I')insert(str);
- else cout<<query(str)<<endl;
- }
- }

1、并查集可以非常快速地执行将两个集合合并,或询问两个元素是否在同一个集合中两个操作


优化:路径压缩优化
2、实现
- #include<bits/stdc++.h>
- //836 并查集 集合合并和判断
- using namespace std;
- const int N=1e5+10;
- int p[N];//存父节点编号
- int n,m;
- int find(int x)//返回祖宗结点
- {
- //递归求解
- if(p[x]!=x)p[x]=find(p[x]);
- return p[x];//递归终止条件
- }
- int main()
- {
- cin>>n>>m;
- for(int i=0;i<n;i++)p[i]=i;
- while(m--)
- {
- char op[2];//char不会忽略字符和回车,读字符串会忽略字符和回车
- int a,b;
- cin>>op>>a>>b;//两种输入方式都可以
- //scanf("%s%d%d",op,&a,&b);
- if(op[0]=='M')p[find(a)]=find(b);//合并两个集合
- else
- {
- if(find(a)==find(b))puts("Yes");
- else puts("No");
- }
- }
- }

3、并查集例题计算连通块中的点的数量以及合并连通块
维护一个size数组,只有根结点有效,初始化为1,每次合并两个树的时候,更新size。
- #include<bits/stdc++.h>
- //837 连通块中点的数量
- using namespace std;
- const int N=1e5+10;
- int p[N];//存父节点编号
- int n,m;
- int size[N];//连通块中点的数量
- //只有根结点中的size是有意义的
- int find(int x)//返回祖宗结点
- {
- //递归求解
- if(p[x]!=x)p[x]=find(p[x]);
- return p[x];//递归终止条件
- }
- int main()
- {
- cin>>n>>m;
- for(int i=0;i<n;i++)p[i]=i,size[i]=1;
- while(m--)
- {
- char op[2];//char不会忽略字符和回车,读字符串会忽略字符和回车
- int a,b;
- cin>>op;//两种输入方式都可以
- if(op[0]=='C')
- {
- scanf("%d%d",&a,&b);
- if(find(a)==find(b))continue;
- //当要结合的两个点已经在同一个集合里面
- //下面不能再在size上加数了
- size[find(b)]+=size[find(a)];
- //先更新size
- p[find(a)]=find(b);
-
- }
- else if(op[1]=='1')
- {
- scanf("%d%d",&a,&b);
- if(find(a)==find(b))puts("Yes");
- else puts("No");
- }
- else
- {
-
- cin>>a;
- cout<<size[find(a)]<<endl;
- }
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。