我英语太差了~~处于小学水平,碰到英语题~~唉,不想说,看了别人的解题报告中的题目大意之后才能做,我就转达下题目大意:输入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?)~~~~