链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805068539215872
题解:很简单的并查集,这可能是我在PTA上写过的最长的代码了
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M = int(1e5); struct p { int ind; int fa, ma; int cnt; int area; int peo; double Area; p() { cnt = area = Area = 0; fa = peo = 0; } //int f; }a[M],ans[M]; int root[M]; void init() { for (int i = 0; i <= M; i++) root[i] = i; } int Find(int x) { int r = x; while (root[r] != r) r = root[r]; int i; while (x != r) { i = root[x]; root[x] = r; x = i; } return r; } void join(int x, int y) { int fx = Find(x); int fy = Find(y); if (fx > fy)root[fx] = fy; else root[fy] = fx; } bool cmp(p a, p b) { if (a.Area == b.Area) return a.ind < b.ind; else return a.Area > b.Area; } int k, x,sum; int main() { init(); int n; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i].ind >> a[i].fa >> a[i].ma>>k; if (a[i].fa != -1) join(a[i].ind, a[i].fa); if (a[i].ma != -1) join(a[i].ind, a[i].ma); for (int j = 0; j < k; j++) { cin >> x; join(a[i].ind, x); } cin >> a[i].cnt >> a[i].area; } for (int i = 0; i < n; i++) { int r = Find(a[i].ind); ans[r].ind = r; ans[r].area += a[i].area; ans[r].cnt += a[i].cnt; ans[r].fa = -1;//? } for (int i = 0; i < M; i++) { ans[Find(i)].peo++; if (ans[i].fa == -1) sum++; } for (int i = 0; i < M; i++) { if (ans[i].fa == -1) ans[i].Area = (double)ans[i].area / ans[i].peo; } cout << sum << endl; sort(ans, ans + M, cmp); for (int i = 0; i < sum; i++) { printf("%.4d %d %.3lf %.3lf\n", ans[i].ind, ans[i].peo, (double)ans[i].cnt / ans[i].peo, ans[i].Area); } return 0; }