CCCC L2 007 家庭房产 并查集
最开始看到这个题,想不到只用并查集,在某一个如果同时又两个其他家庭包括的人怎么办,所有开了一个home类,想通过Home之间的合并解决这个问题,最后由于内容过于庞大而超时。
参考网上的思路用并查集可以实现这个过程
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct DATA {
int id, fid, mid;
int k;
int sid[10];
int n, s;
} d[1005];
struct ANS {
int id, num, a1, a2;
double b1, b2;
} ans[10005], res[10005];
int fa[10005];
bool vis[10005], has[10005];
bool cmp(ANS a, ANS b) {
if(a.b2 == b.b2)
return a.id < b.id;
return a.b2 > b.b2;
}
void UF_set() {
for(int i = 0; i <= 9999; i++)
fa[i] = i;
}
int Find(int x) {
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
/*不对某个人确定他的归属家族而是按家族合并*/
void Union(int a, int b) {
int r1 = Find(a);
int r2 = Find(b);
if(r1 != r2) {
if(r1 < r2)
fa[r2] = r1;
else
fa[r1] = r2;
}
}
int main() {
UF_set();
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d %d %d", &d[i].id, &d[i].fid, &d[i].mid);
vis[d[i].id] = true;
if(d[i].fid != -1) {
vis[d[i].fid] = true;
Union(d[i].id, d[i].fid);
}
if(d[i].mid != -1) {
vis[d[i].mid] = true;
Union(d[i].id, d[i].mid);
}
scanf("%d", &d[i].k);
for(int j = 0; j < d[i].k; j++) {
scanf("%d", &d[i].sid[j]);
if(d[i].sid[j] != -1) {
vis[d[i].sid[j]] = true;
Union(d[i].id, d[i].sid[j]);
}
}
scanf("%d %d", &d[i].n, &d[i].s);
}
for(int i = 0; i < n; i++) {
int id = Find(d[i].id);
ans[id].id = id;
ans[id].a1 += d[i].n;
ans[id].a2 += d[i].s;
}
for(int i = 0; i < 10000; i++)
if(vis[i])
ans[Find(i)].num ++;
int cnt = 0;
for(int i = 0; i < 10000; i++) {
if(vis[i]) {
int id = Find(i);
if(!has[id]) {
has[id] = true;
res[cnt].b1 = (double)ans[id].a1 / (double)ans[id].num;
res[cnt].b2 = (double)ans[id].a2 / (double)ans[id].num;
res[cnt].id = id;
res[cnt ++].num = ans[id].num;
}
}
}
sort(res, res + cnt, cmp);
printf("%d\n", cnt);
for(int i = 0; i < cnt; i++) {
if(res[i].id < 10)
printf("000%d %d %.3f %.3f\n", res[i].id, res[i].num, res[i].b1, res[i].b2);
else if(res[i].id < 100)
printf("00%d %d %.3f %.3f\n", res[i].id, res[i].num, res[i].b1, res[i].b2);
else if(res[i].id < 1000)
printf("0%d %d %.3f %.3f\n", res[i].id, res[i].num, res[i].b1, res[i].b2);
else
printf("%d %d %.3f %.3f\n", res[i].id, res[i].num, res[i].b1, res[i].b2);
}
}