POJ 并查集
来源:互联网 发布:数据库先学哪个 编辑:程序博客网 时间:2024/05/07 18:20
POJ1308
并查集:判断是否属于同一棵树
数组:记录入度
#include <cstdio>#include <cstdlib>#include <set>#include <iterator>#define MAXN 10001using namespace std;set<int> st;set<int>::iterator it;int father[MAXN];int degree[MAXN];//入度void makeSet(){ for (int i=1; i<MAXN; i++) { father[i]=i; degree[i]=0; }}int findSet(int x){ return x==father[x]?x:father[x]=findSet(father[x]); /* if (x!=father[x]) { father[x]=findSet(father[x]);//路径压缩 } return father[x];*/}void unionSet(int x,int y){ int fx=findSet(x); int fy=findSet(y); father[fy]=fx;}int main(){ bool fail; int k=1; int a,b; while (scanf("%d%d",&a,&b)&&(a!=-1&&b!=-1)) { if (a==0&&b==0) {//空树 printf("Case %d is a tree.\n",k++); continue; } st.clear();//清空 st.insert(a); st.insert(b); makeSet();//初始化 unionSet(a, b); ++degree[b];//入度++ while (scanf("%d%d",&a,&b)&&(a&&b)) {//a,b!=0 st.insert(a); st.insert(b); unionSet(a, b); ++degree[b]; } int fs=findSet(father[*st.begin()]); int zeroCnt=0;//统计有多少个入度为0的节点 fail=false; for (it=st.begin(); it!=st.end(); ++it) { if (fs!=findSet(father[*it])) {//树中节点的祖先都一样,否则不是树 fail=true; break; } if (degree[*it]>1) {//入度>1不是树 fail=true; break; } if (degree[*it]==0) {//统计根 ++zeroCnt; } } printf("Case %d ",k++); if (fail||zeroCnt!=1) {//根不是一个 printf("is not a tree.\n"); }else{ printf("is a tree.\n"); } } return 0;}
POJ1611
#include <cstdio>#include <iostream>using namespace std;const int MAXN=30001;int fa[MAXN];//父节点int ran[MAXN];int num[MAXN];//节点数void makeSet(int n){ for (int i=0; i<n; i++){ fa[i]=i; num[i]=1; }}int findSet(int x){ int r=x; while (fa[r]!=r) {//find the root r=fa[r]; } int t=x; while (x!=r) {//compress t=fa[x]; fa[x]=r; x=t; } return r;}void unionSet(int x,int y){ int fx=findSet(x); int fy=findSet(y); if (num[fx]>num[fy]) { fa[fy]=fx; num[fx]+=num[fy]; }else{ fa[fx]=fy; num[fy]+=num[fx]; } }int main(){ int m,n; while (scanf("%d %d",&n,&m)) { if (m==0&&n==0) { break; } if (m==0) {//group is 0 printf("1\n"); continue; } makeSet(n);//n student int t; for (int i=0; i<m; i++) { scanf("%d",&t); int ni,nj; scanf("%d",&ni); for (int j=1; j<t; j++) { scanf("%d",&nj); if (findSet(ni)!=findSet(nj)) { unionSet(ni, nj); } ni=nj; } } int res=findSet(0); printf("%d\n",num[res]); } return 0;}
POJ2524
#include <cstdio>#include <iostream>using namespace std;const int MAXN=50001;int fa[MAXN];int ran[MAXN];int res;void makeSet(int n){ for (int i=0; i<n; i++) { fa[i]=i; ran[i]=1; }}int findSet(int x){ int r=x; while (fa[r]!=r){//find the root r=fa[r]; } int t=x; while (x!=r) {//compress t=fa[x]; fa[x]=r; x=t; } return r;}void unionSet(int x,int y){ int fx=findSet(x); int fy=findSet(y); if (ran[x]>ran[y]) { fa[fy]=fx; }else{ fa[fx]=fy; if (ran[fx]==ran[fy]) { ran[fy]++; } } res--;//kind-1}int main(){ int m,n,k=1; while (scanf("%d%d",&n,&m)) { if (n==0&&m==0) { break; } makeSet(n); res=n;//n kind int x,y; for (int i=0; i<m; i++) { scanf("%d%d",&x,&y); if (findSet(x)!=findSet(y)) { unionSet(x, y); } } printf("Case %d: %d\n",k,res); k++; } return 0;}
POJ1182
使用带权值的并查集
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>using namespace std;const int LYD=50010;//animal number upperstruct Animal{ int num; int parent; int relation;//relationship with father node};Animal ani[LYD];int res=0;int findParent(Animal *node){ int tmp; if (node->parent==node->num) {//root return node->parent; } tmp=node->parent; //printf("Animal %d s Parent is %d\n",node->num,node->parent); node->parent=findParent(&ani[node->parent]); node->relation=(ani[tmp].relation+node->relation)%3; return node->parent;}void UnionSet(int x,int y,int a,int b,int d){ ani[b].parent=a; ani[b].relation=((3-ani[y].relation)+(d-1)+ani[x].relation)%3;}void initAnimal(int n){ for (int i=1; i<=n; i++) { ani[i].num=i; ani[i].parent=i; ani[i].relation=0; }}int main(){ int N,K; int d,X,Y; scanf("%d%d",&N,&K); initAnimal(N); for (int i=0; i<K; i++) { scanf("%d%d%d",&d,&X,&Y); if (X>N||Y>N) {//error case2 res++; }else{ if (d==2&&X==Y) {//error case3 res++; }else{ int a=findParent(&ani[X]); int b=findParent(&ani[Y]); if (a!=b) {//different set UnionSet(X, Y, a, b, d); }else{//same set switch (d) { case 1: if (ani[X].relation!=ani[Y].relation) { res++; } break; case 2: if (((ani[Y].relation+3-ani[X].relation)%3)!=1) { res++; } break; default: break; } } } } } printf("%d\n",res); return 0;}
0 0
- Poj 并查集
- poj并查集
- POJ 并查集
- poj 2524 并查集
- POJ 2236 并查集
- 并查集 POJ 2524
- 并查集 POJ 1611
- POJ 1182 并查集
- POJ 1703 并查集
- POJ 2492 并查集
- poj-1308 并查集
- poj-1703 并查集
- poj-2524 并查集
- 【并查集】POJ-1611
- POJ - 2492 并查集
- poj 1703 并查集
- 并查集----poj解题
- POJ 1703 (并查集)
- weka学习1:Eclipse环境下整合weka
- 马士兵struts2视频教程第四十九集
- 使用ggplot2画图
- 暴力拆解《Numerical Optimization》之信任域方法(上)
- 单例模式在iOS中的应用——三种创建单例方法对比
- POJ 并查集
- windows常用软件
- 有向图的强连通分支
- Elasticsearch的javaAPI之get,delete,bulk
- 116. Index of super-prime
- LA4329(树状数组)
- JavaWeb监听器Listener
- 117. Counting
- hihocoder 1014 trie树