原题目参见:Family Property
求成员个数,等价求连通分量个数。方法采用BFS,DFS遍历取总分量个数。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 100010;
map<int, int>idtoi; // 99999 - 0;
map<int, int>itoid; // 0 - 99999;
int n = 0;
vector<vector<int> >adj;
double m[maxn];
double area[maxn];
bool vis[maxn] = { 0 };
int geti(int id) {
//因为有插入vector的操作,所以这个函数只能在处理输入数据的时候使用。
if (id == -1) {
return id;
}
else if (idtoi.count(id)) {
return idtoi[id];
}
else {
idtoi[id] = n++;
itoid[n - 1] = id;
vector<int> emp;
adj.push_back(emp);
return idtoi[id];
}
}
struct Family {
int id, num;
double mm, areaa;
void print() {
printf("%04d %d %.3lf %.3lf\n", id, num, mm, areaa);
}
};
Family BFS(int s) {
int num = 0;
double mm = 0, areaa = 0;
vector<int> v;
queue<int> q;
num++;
vis[s] = 1;
v.push_back(itoid[s]);
areaa += area[s];
mm += m[s];
q.push(s);
while (!q.empty()) {
s = q.front();
q.pop();
for (auto fri : adj[s]) {
if (!vis[fri]) {
num++;
vis[fri] = 1;
v.push_back(itoid[fri]);
areaa += area[fri];
mm += m[fri];
q.push(fri);
}
}
}
sort(v.begin(), v.end());
int father = v[0];
areaa /= num;
mm /= num;
Family fam;
fam.id = father;
fam.num = num;
fam.mm = mm;
fam.areaa = areaa;
return fam;
}
int cmp(Family a, Family b) {
if (a.areaa != b.areaa) {
return a.areaa > b.areaa;
}
else {
return a.id < b.id;
}
}
int BFSTravel() {
vector<Family> families;
Family family;
for (int i = 0; i < n; i++) {
if (!vis[i]) {
family = BFS(i);
families.push_back(family);
}
}
sort(families.begin(), families.end(), cmp);
printf("%d\n", families.size());
for (auto fff : families) {
fff.print();
}
return 0;
}
int main()
{
fill(m, m + maxn, 0);
fill(area, area + maxn, 0);
int N, id, father, mother, k, child, icc;
double mm, areaa;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d%d%d%d", &id, &father, &mother, &k);
id = geti(id);
father = geti(father);
mother = geti(mother);
if (father != -1) {
adj[id].push_back(father);
adj[father].push_back(id);
}
if (mother != -1) {
adj[id].push_back(mother);
adj[mother].push_back(id);
}
for (int j = 0; j < k; j++) {
scanf("%d", &child);
child = geti(child);
adj[id].push_back(child);
adj[child].push_back(id);
}
scanf("%lf%lf", &m[id], &area[id]);
}
BFSTravel();
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
求成员个数,等价并查集个数。参见1114 Family Property
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 10010;
struct Node {
int id, count=0, area=0, set=0;
};
vector<Node> vec(maxn);
vector<Node> roots(maxn);
vector<Node> ans;
int father[maxn];
int findFather(int x) {
int root = x;
while (root != father[root])root = father[root];
while (father[x] != root) {
int z = father[x];
father[x] = root;
x = z;
}
return root;
}
int cmp(Node a, Node b) {
double ea = (double)a.area / a.count;
double eb = (double)b.area / b.count;
return ea != eb ? ea > eb:a.id < b.id;
}
int Union(int a, int b) {
int fa = findFather(a);
int fb = findFather(b);
if (fa != fb)father[max(fa, fb)] = min(fa, fb);
return 0;
}
int main() {
for (int i = 0; i < maxn; i++)father[i] = i;
int a, b, c, d, e, f, g, n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d%d%d", &a, &b, &c, &d);
if (b != -1)Union(a, b);
if (c != -1)Union(a, c);
for (int j = 0; j < d; j++) {
scanf("%d", &e);
Union(a, e);
}
scanf("%d %d", &vec[a].set, &vec[a].area);
}
for (int i = 0; i < maxn; i++) {
int r = findFather(i);
roots[r].id = r;
roots[r].count++;
roots[r].set += vec[i].set;
roots[r].area += vec[i].area;
}
for (int i = 0; i < maxn; i++) {
if (roots[i].area > 0) ans.push_back(roots[i]);
}
sort(ans.begin(), ans.end(), cmp);
printf("%d\n", ans.size());
for (auto x : ans) {
printf("%04d %d %.3lf %.3lf\n", x.id, x.count, (double)x.set / x.count, (double)x.area / x.count);
}
return 0;
}