[置顶] c4-cccc L2-007 家庭房产 并查集
这个题我做了好久,终于用自己的思路Ac了/doge
把每个人做一个集合,其实可以把id,num,house,area,pre这几个数组变成该成这种
class Person { public: int id, num, area, house, pre; }person[maxn];
对人进行合并操作,每次插入一个人判断这个人是否存在,也就是他的id是否存在,id存在则增加一个人否则不加人只合并,
每次通过find和对minid和person的比较进行合并,只保留其中最高级下表较小的,这样就保证了最后的num不为0的人的id满足要求。这里有个坑点就是把两个下标一样的合并时,由于要被合并者置零,会导致最后很多家庭的全部成员死于莫名AOE,
所以这是应该不操作。
最后把num不为0的人储存在一个vector里,按要求排个序,在输出就可以了。
可以看到速度还是不慢的。
代码如下::
#include<iostream> #include<cstring> #include<ctime> #include<vector> #include<cstdio> #include<algorithm> using namespace std; #define maxn 10005 int id[maxn], num[maxn], house[maxn], area[maxn], pre[maxn]; typedef struct Ans { int id; int num; double house; double area; Ans(int id, int num, int house, int area) { this->id = id; this->num = num; this->house = 1.0*house / num; this->area = 1.0*area / num; } void print() { printf("%04d %d %.3lf %.3lf\n", id, num, house, area); } }; int find(int i) { if (pre[i] == i)return i; else { return i=find(pre[i]); } } int un(int number, int minid) { if (number != -1) { if (id[number]) { id[number] = 0; if (number != pre[number]) { number = find(number); } num[number]++; } else { if (number != pre[number]) { number = find(number); } } if (number < minid) {//合并number和minid num[number] += num[minid]; house[number] += house[minid]; area[number] += area[minid]; num[minid] = 0; house[minid] = 0; area[minid] = 0; pre[minid] = number; minid = number; } else if(number>minid){ num[minid] += num[number]; house[minid] += house[number]; area[minid] += area[number]; num[number] = 0; house[number] = 0; area[number] = 0; pre[number] = minid; } } return minid; } vector<Ans> ans; bool cmp(const Ans a, const Ans b) { if (a.area == b.area)return a.id < b.id; return a.area > b.area; } int main(int argc,char argv[]) { int minid; int t;//numOfHouses int k;//numOfKids int number;//numberOfPerson int s;//areas int n;//house cin >> t; for (int i = 0; i < maxn; i++) { pre[i] = i; num[i] = 0; id[i] = 1; } while (t--) { cin >> minid; if (id[minid]) { id[minid] = 0; if (minid != pre[minid]) { minid = find(minid); } num[minid]++; } else { if (minid != pre[minid]) { minid = find(minid); } } cin >> number; if(number!=-1) minid = un(number, minid); cin >> number; if (number!=-1) minid = un(number, minid); cin >> k; while (k--) { cin >> number; if (number!=-1) minid = un(number, minid); } cin >> n >> s; area[minid] += s; house[minid] += n; } int x ; for (int i = 0; i < maxn; i++) { if (num[i] != 0) { x = find(i); if (x < i) { un(i, x); } else { un(x, i); } } } for (int i = 0; i < maxn; i++) { if (num[i] != 0) { ans.push_back(Ans(i, num[i], house[i], area[i])); } } printf("%d\n", ans.size()); sort(ans.begin(), ans.end(), cmp); for (Ans i : ans) { i.print(); } return 0; }