暑假训练专题二 并查集的理解 优先队列
2012-07-02 21:08
429 查看
并查集主要是体现在并和查的概念上,这个很重要,判断两个元素是否属于同一个集合,将属于不同的集合合并,不合并不属于相同的集合,这样就可以了。
对于集合个数的判断: 主要是要找的这个节点的parent值是否等于自身,x==p[x].parent,如果相等则成立。
今天做了 3道并查集的问题~~
了解了并查集用到的三个子函数,很有用:
1:数组数据的初始化。
2:优化后对树的根结点的查找。
3:优化后的合并树,是按照秩(树的高度)来合并的。
这是用到的三个代码模版。
下面开始 对例题尽心分析。
杭电1232 畅通工程 就是对并查集的简单应用。
还有就是 poj 2524 Ubiquitous Religions和 这道题完全类似。
还有一道是 poj The Suspects 有略微的变型~~要注意。
优先队列:
是按从大到小的顺序输出的。
直接进行输入输出,进行排序;
得出的结果:
下面是对其尽心逆着排序:即从小到大输出:
下面是对两组数据的排序:
根据关键字来进行排序;
对于集合个数的判断: 主要是要找的这个节点的parent值是否等于自身,x==p[x].parent,如果相等则成立。
今天做了 3道并查集的问题~~
了解了并查集用到的三个子函数,很有用:
1:数组数据的初始化。
void Make_set() { int i; for(i=0;i<n;i++) { p[i].data=i; p[i].rank=0; p[i].parent=i; } }
2:优化后对树的根结点的查找。
int Find(int x) { if(x!=p[x].parent) p[x].parent=Find(p[x].parent); return p[x].parent; }
3:优化后的合并树,是按照秩(树的高度)来合并的。
void Union(int x,int y) { x=Find(x); y=Find(y); if(x!=y){ if(p[x].rank>p[y].rank){p[y].parent=x;} else { p[x].parent=y; if(p[x].rank==p[y].rank)p[y].rank++; } } }
这是用到的三个代码模版。
下面开始 对例题尽心分析。
杭电1232 畅通工程 就是对并查集的简单应用。
#include<stdio.h> #include<string.h> typedef struct node{ int data; int rank; int parent; }UFSTree; UFSTree p[1010]; void Make_set(int n); int Find(int x); void Union(int x,int y); int a[1010]; int main() { int n,m,road1,road2,i,j,k,num,flag; while(scanf("%d %d",&n,&m)&&n!=0) { if(m==0){printf("%d\n",n-1);continue;} Make_set(n); for(i=1;i<=m;i++) { scanf("%d %d",&road1,&road2); Union(road1,road2); } j=0; memset(a,0,sizeof(a)); a[j]=Find(1);j++; for(i=2;i<=n;i++) { flag=0; num=Find(i); for(k=0;k<j;k++) { if(a[k]==num){flag=1;break;} } if(flag==0){a[j]=num;j++;} } printf("%d\n",j-1); } } void Make_set(int n) { int i; for(i=1;i<=n;i++) { p[i].data=i; p[i].rank=0; p[i].parent=i; } } int Find(int x) { if(x!=p[x].parent) p[x].parent=Find(p[x].parent); return p[x].parent; } void Union(int x,int y) { x=Find(x); y=Find(y); if(x!=y){ if(p[x].rank>p[y].rank){p[y].parent=x;} else { p[x].parent=y; if(p[x].rank==p[y].rank){ p[y].rank++; } } } }
还有就是 poj 2524 Ubiquitous Religions和 这道题完全类似。
还有一道是 poj The Suspects 有略微的变型~~要注意。
优先队列:
是按从大到小的顺序输出的。
直接进行输入输出,进行排序;
#include<iostream> #include<queue> using namespace std; int main() { int a[10]={4,3,2,5,4,2,3,2,10,9},i; priority_queue<int> qi; for(i=0;i<10;i++) { qi.push(a[i]); } for(i=0;i<10;i++) { cout<<qi.top()<<" "; qi.pop(); } }
得出的结果:
下面是对其尽心逆着排序:即从小到大输出:
#include<iostream> #include<queue> using namespace std; int main() { priority_queue<int ,vector<int>, greater<int> > q2; int i,a[9]={4,3,2,1,5,6,7,8,9}; for(i=0;i<9;i++) { q2.push(a[i]); } for(i=0;i<9;i++) { cout<<q2.top()<<" "; q2.pop(); } cin>>a[i]; }
下面是对两组数据的排序:
根据关键字来进行排序;
相关文章推荐
- 拓扑排序 详解 + 并查集 详解 + 最小生成树(MST)详解 【普利姆算法 + 优先队列优化 & 克鲁斯卡尔算法】
- 暑假训练专题三 bellman-ford 求两点之间的最短路径
- 蓝桥杯 算法训练 最短路 【SPFA队列优化 + dijkstra优先队列优化】
- 容易理解的python用队列实现广度优先遍历文件
- Poj 3233 矩阵快速幂,暑假训练专题中的某一道题目,矩阵快速幂的模板
- 暑假训练3-图论专题
- 【HDU 3810】 Magina (01背包,优先队列优化,并查集)
- dp暑假专题 训练记录
- poj 3465 贪心+优先队列 叉姐的魔法训练
- 【暑假专题训练#数据结构】
- [二叉树专题]:广度优先:按层次遍历二叉树的非递归实现||使用队列实现层次遍历二叉树
- 二分暑假专题 训练记录 2017-7-29
- 【算法篇】栈和队列专题之广度优先遍历和深度优先遍历
- 暑假训练2-DP专题
- 暑假训练4-数据结构专题
- 暑假训练专题一 博弈
- 优先队列重载(理解)
- 并查集专题训练解题报告
- 总结_六天专题:栈和队列,树,并查集,KMP匹配算法
- pku 1456 Supermarket 贪心优先队列的应用 or 并查集