我英语太差了~~处于小学水平,碰到英语题~~唉,不想说,看了别人的解题报告中的题目大意之后才能做,我就转达下题目大意:输入n,然后输入n组数据,表示a与b的关系,最后求出关系最多一组的个数,比方说第一组数据中的最多人一组的就是:{1,2,5,6}~~~
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAX=10000010; int father[MAX],rank[MAX],n,sum; void Init() { for(int i=0;i<MAX;i++) { father[i]=i; rank[i]=1; } } int Find(int u)//查找u的根结点 { return father[u]==u?u:Find(father[u]);//路径压缩 } void Union(int u,int v) { u=Find(u); v=Find(v); if(u==v) return ; if(rank[u]>rank[v]) { rank[u]+=rank[v]; if(rank[u]>sum) sum=rank[u]; father[v]=u; } else { rank[v]+=rank[u]; if(rank[v]>sum) sum=rank[v]; father[u]=v; } } int main() { int u,v; while(scanf("%d",&n)!=EOF) { Init(); sum=(n==0?1:0);//WA了几次~~没想清楚,discuss中提到了当n==0时输出1~呵呵 for(int i=0;i<n;i++) { scanf("%d%d",&u,&v); Union(u,v); } printf("%d\n",sum); } return 0; }
hdu 1232(畅通工程)题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232
使用并查集求满足连通图所需边数,只需要判断有几个父结点即可。需要用到查询操作。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAX=1010; int father[MAX],rank[MAX],n,m,sum; void Init() { for(int i=0;i<=n;i++)//初始化的时候得注意下~ { father[i]=i; rank[i]=1; } } int Find(int u)//查找u的根结点 { return father[u]==u?u:Find(father[u]); } void Union(int u,int v) { u=Find(u); v=Find(v); if(u==v) return ; if(u!=v) father[u]=v;//不做启发式合并,不同直接合并即可~只是需要时间长 /*********************** if(rank[u]>rank[v]) //其实这个rank可以不要,因为只需判断父结点即可, { rank[u]+=rank[v]; father[v]=u; } else { rank[v]+=rank[u]; father[u]=v; } ***********************/ } int main() { int u,v; while(scanf("%d",&n)&&n) { scanf("%d",&m); Init(); sum=0; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); Union(u,v); } for(int i=1;i<=n;i++) if(father[i]==i) sum++;//不管有几个独立的图,由于路径压缩,同一个图的每个结点的父结点都是一样的,所以只需判断父结点的个数即可 printf("%d\n",sum-1); } return 0; }
和上题一样的题目是:hdu 1213(How Many Tables?)~~~~