(一)简介
并查集是维护集合的数据结构 它支持合并 查找功能
本身实现依靠
int father[N];
father[i]表示元素i 的结点
例如 father[1] = 2;表示元素1的父亲结点时2;
father[i] = i ; 说明元素i 是该集合的根节点
(二)操作集
for(int i = 1; i <= n; i ++)
father[i] = i;
int findfather(int x)
{
while(x != father[x])
x = father[x];
return x;
}
int findfather(int x)
{
if(x == father[x]) return x;
else return findfather(father[x]);
}
void Union(int a,int b)
{
int fa = findfather(a);
int fb = findfather(b);
if(fa != fb)
father[fa] = fb;
}
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 10000000;
int father[maxn];
int isroot[maxn];
int course[maxn];
bool cmp(int x,int y)
{
return x>y;
}
int findfather(int x)
{
return father[x] == x ? x : father[x] =findfather(father[x]);
}
void Union(int x,int y)
{
int a = findfather(x);
int b = findfather(y);
if(a!=b)
father[a] = b;
}
void init()
{
for(int i = 0; i< maxn ; i++)
father[i] = i;
}
int main()
{
init();
int n,m,k;
cin>>n;
for(int i =1; i <= n ; i++)
{
scanf("%d:",&m);
for(int j = 0; j < m ;j ++)
{
cin>>k;
if(course[k] == 0)
course[k] = i;
Union(i,course[k]);
}
}
for(int i =1 ; i <= n;i++)
isroot[findfather(i)]++;
int ans =0 ;
for(int i = 1; i <= n;i++)
if(isroot[i] != 0)
ans++;
cout<<ans<<endl;
sort(isroot , isroot + n+1 ,cmp);
for(int i = 0 ; i<ans; i++)
{
if(i)
cout<<" ";
cout<<isroot[i];
}
}
1114 Family Property (25分)
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 10000;
struct
{
int id,fid,mid,num,area;
int cid[10];
}data[maxn];
struct node
{
int id,people;
double num,area;
bool flag = false;
}ans[maxn];
int father[maxn];
bool vis[maxn];
int findfather(int x)
{
return father[x] == x?x : father[x] = findfather(father[x]);
}
void Union(int a,int b)
{
int faA = findfather(a);
int faB = findfather(b);
if(faA > faB)
father[faA] = faB;
else if(faA < faB)
father[faB] = faA;
}
int cmp1(node a, node b)
{
if(a.area != b.area)
return a.area > b.area;
else
return a.id < b.id;
}
int main()
{
int n,k,cnt = 0;
cin>>n;
for(int i =0 ; i< maxn ; i++)
father[i] = i;
for(int i =0 ; i < n ; i++)
{
cin>>data[i].id>>data[i].fid>>data[i].mid>>k;
vis[data[i].id] = true;
if(data[i].fid != -1)
{
vis[data[i].fid] = true;
Union(data[i].fid,data[i].id);
}
if(data[i].mid != -1)
{
vis[data[i].mid] = true;
Union(data[i].mid,data[i].id);
}
for(int j = 0 ; j < k ; j ++)
{
cin>>data[i].cid[j];
vis[data[i].cid[j]] = true;
Union(data[i].cid[j] , data[i].id);
}
cin>>data[i].num>>data[i].area;
}
for(int i = 0 ; i < n ;i++)
{
int id = findfather(data[i].id);
ans[id].id = id;
ans[id].num += data[i].num;
ans[id].area+= data[i].area;
ans[id].flag = true;
}
for(int i = 0 ; i <maxn ; i++)
{
if(vis[i])
ans[findfather(i)].people++;
if(ans[i].flag)
cnt++;
}
for(int i = 0 ; i < maxn ; i ++)
{
if(ans[i].flag)
{
ans[i].num = (double)(ans[i].num * 1.0 / ans[i].people);
ans[i].area = (double)(ans[i].area * 1.0 / ans[i].people);
}
}
sort(ans,ans+maxn,cmp1);
cout<<cnt<<endl;
for(int i = 0 ; i < cnt ; i ++)
printf("%04d %d %.3f %.3f\n",ans[i].id,ans[i].people,ans[i].num,ans[i].area);
}