POJ 2524 Ubiquitous Religions
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,maxnum;
int father[50005],num[50005];
void makeset(int n)//创建并查集
{
for(int i=0;i<=n;i++){
father[i]=i;//每个元素的father为自身
num[i]=1;//每类均只有一个
}
}
int findset(int x)
{
if(father[x]!=x){
father[x]=findset(father[x]);
}
return father[x];
}
void Union(int a,int b)
{
int x=findset(a);
int y=findset(b);
if(x==y) return;
if(num[x]<=num[y]){
father[x]=y;
num[y]+=num[x];
maxnum--;
}
else{
father[y]=x;
num[x]+=num[y];
maxnum--;
}
}
int main()
{
int Case=1;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0) break;
maxnum=n;
makeset(n);
int a,b;
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
Union(a,b);
}
printf("Case %d: %d\n",Case++,maxnum);
}
return 0;
}
HOJ 1225 - Supermarket
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int h[10001];
struct product
{
int p,d;
bool operator < (const product &a){
return a.p < p;
}
}pd[10001];
inline int find(int x)
{//并查集查找 递归的路径压缩
if (h[x]==x) return x;
h[x]=find(h[x]);
return h[x];
}
int main()
{
int n;
while(scanf("%d",&n)==1)
{
int ans=0;
int md=0;//记录最大截止时间
for (int i=1;i<=n;i++)
{
scanf("%d %d",&pd[i].p,&pd[i].d);
if (md<pd[i].d) md=pd[i].d;
}
sort(pd+1,pd+n+1);//完全按价值从大到小排序,不考虑时间
for (int i=0;i<=md;i++)
h[i]=i;//初始化并查集,每个时间的最近空闲时间都是其本身
//h[i]表示第i个单位时间内向前最近[保证尽量迟]是哪一个单位时间有空余
for (int i=1;i<=n;i++){
if (find(pd[i].d))
{
ans+=pd[i].p;
h[h[pd[i].d]]=h[pd[i].d]-1;
//将当前时间的最近空闲时间置为h[pd[i].d]-1
}
}
printf("%d\n",ans);
}
return 0;
}
HOJ 1564 - The Suspects
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int h[30001];
int temp[30001];
int findset(int x)
{
if(h[x]!=x){
h[x]=findset(h[x]);
}
return h[x];
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0) break;
for(int i=0;i<n;i++){
h[i]=i;
}
while(m--){
int k;
scanf("%d",&k);
int mi=n;
for(int i=0;i<k;i++){
int x;
scanf("%d",&x);
temp[i]=findset(x);
if(temp[i]<mi){
mi=temp[i];
}
}
for(int i=0;i<k;i++){
h[temp[i]]=mi;
}
}
int num=0;
for(int i=0;i<n;i++){
if(findset(i)==0){
num++;
}
}
printf("%d\n",num);
}
return 0;
}
HOJ 1642 - Corporative Network
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int father[20001],dis[20001];
inline int abs(int x){
return x>0?x:-x;
}
int findset(int x)
{
if(father[x]==x) return x;
findset(father[x]);//更新沿途节点的距离值
dis[x]+=dis[father[x]];
father[x]=findset(father[x]);//路径上元素的父亲指针都指向根结点(路径压缩)
return father[x];
}
void unionset(int x,int y){
dis[x]=abs(x-y)%1000;
father[x]=y;
}
int main() {
int t;
scanf("%d",&t);
while(t--){
int n;
memset(dis, 0, sizeof(dis));
scanf("%d",&n);
for(int i=1;i<=n;i++){
father[i]=i;
}
char op;
while(scanf("%c",&op)&&op!='O'){
if(op=='I'){
int a,b;
scanf("%d%d",&a,&b);
unionset(a,b);
}
else if(op=='E'){
int ans;
scanf("%d",&ans);
findset(ans);
printf("%d\n",dis[ans]);
}
}
}
return 0;
}