[poj 1611]The Suspects[并查集模板][递归与非递归实现]
来源:互联网 发布:智能仓库管理系统 源码 编辑:程序博客网 时间:2024/05/16 13:52
/*Model One*///364K47MS[poj上递归略快一些~]#include<iostream>#include<cstring>using namespace std;const int MAXSIZE = 30005;int parent[MAXSIZE];//根节点储存-num(该树节点数),子节点储存父节点int Find(int x){//递归的路径压缩 if(parent[x]>=0) { parent[x] = Find(parent[x]); return parent[x]; } else return x;}void Union(int root1, int root2){ int x = Find(root1),y = Find(root2); if(x==y) return; if(parent[x]<parent[y]) { parent[x] += parent[y]; parent[y] = x; } else{//启发式合并 parent[y] += parent[x]; parent[x] = y; }}void Init(void){ memset(parent,-1,sizeof(parent));}/*Model Two*///364K63MS#include<iostream>#include<cstring>using namespace std;const int MAXSIZE = 30005;int pre[MAXSIZE];//根节点i,pre[i]=-num,其中num是该树的节点数目 //非根节点j,pre[j]=k,其中k是j的父节点int Find(int x){//非递归的路径压缩 int p = x; while(pre[p]>0) p = pre[p];//找到x的根节点p while(x!=p){ int tmp = pre[x];//暂存x的父节点 pre[x] = p;//将x的父节点设为根 x = tmp;//沿路径向上压缩 } return x;//退出时x==p,为根}void Union(int root1,int root2){ int a = Find(root1), b = Find(root2); if(a==b) return; //加权规则合并 if(pre[a]<pre[b])//a的节点数目大于b { pre[a] += pre[b];//将b并为a的子树 pre[b] = a;//b已是中间节点,使其父节点为a即可 } else { pre[b] += pre[a]; pre[a] = b; }}void Init(void){ memset(pre,-1,sizeof(pre));}int main(){ int n,m; while(cin>>n>>m&&(m+n)) { if(m==0) { cout<<"1"<<endl; continue; } Init(); int sum,x,y; for(int j=0;j<m;j++) { cin>>sum>>x; for(int i=1;i<sum;i++) { cin>>y; Union(x,y); } } /*Model One*/ //cout<<-parent[Find(0)]<<endl; /*Model Two*/ cout<<-pre[Find(0)]<<endl; } return 0;}