In a Group Programming Contest, each university is supposed to send n students who must compete independently. The universities are ranked according to the total score of their students. Your job is to generate the ranklist.
It sounds like a simple problem, but what makes it complicated is that we have lost all the teams’ information! What we have is a list of only some of the students’ scores, and some photos taken from the contest sites which shows several students with the same university badge. You just have to recover the ranklist as much as you can.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer
N
(
≤
1000
)
N (≤1000)
N(≤1000). Then
N
N
N lines follow, each gives the infomation of a student in the format:
ID
k
k
k
t
e
a
m
m
a
t
e
1
⋯
t
e
a
m
m
a
t
e
k
teammate_1⋯teammate_k
teammate1⋯teammatek Score
where ID
is a unique 4-digit identification number for a student;
k
(
0
≤
k
≤
5
)
k (0≤k≤5)
k(0≤k≤5) is the number of teammates of this student in a photo;
t
e
a
m
m
a
t
e
i
teammate_i
teammatei's are the ID
's of his/her teammate; and Score
is this student’s score which is in the range [0, 400].
It is guaranteed that each ID
with a Score
is given only once.
Output Specification:
For each case, first print in a line the number of universities (all the students that are related directly or indirectly as teammates are considered in the same university). Then output the partial school ranking in the format:
ID
S
S
c
o
r
e
t
o
t
a
l
Score_{total}
Scoretotal
where ID
is the smallest student ID in the university; S
is the total number of its students; and
S
c
o
r
e
t
o
t
a
l
Score_{total}
Scoretotal is the total score that can be recovered for that university. The universities must be given in descending order of their
S
c
o
r
e
t
o
t
a
l
Score_{total}
Scoretotal, or in ascending order of S
if there is a tie, or in ascending order of ID
if there is still a tie.
Sample Input:
11
7456 3 7457 7458 7459 157
6666 3 5551 5552 7777 100
1234 3 5678 9012 0002 80
8888 0 340
2468 3 0001 0004 2222 110
7777 1 6666 57
3721 1 2333 30
9012 3 1236 1235 1234 10
1235 2 5678 9012 50
2222 4 1236 2468 6661 6662 16
2333 4 3721 6661 6662 6663 44
Sample Output:
4
8888 1 340
0001 15 340
5551 4 157
7456 4 157
Solution:
// Talk is cheap, show me the code
// Created by Misdirection 2021-09-19 13:27:53
// All rights reserved.
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
struct School{
int rootID;
int nums;
int scoreSum;
School(int r, int num, int s){
rootID = r;
nums = num;
scoreSum = s;
}
~School(){}
};
unordered_map<int, int> scores;
unordered_map<int, bool> valid;
unordered_map<int, int> position;
unordered_map<int, bool> vis;
int father[10005];
int n;
vector<School> schools;
int findFather(int a){
int tmp = a;
while(tmp != father[tmp]) tmp = father[tmp];
return tmp;
}
void Union(int a, int b){
int fa = findFather(a);
int fb = findFather(b);
if(fa < fb) father[fb] = fa;
else father[fa] = fb;
return;
}
bool cmp(School &a, School &b){
if(a.scoreSum != b.scoreSum) return a.scoreSum > b.scoreSum;
if(a.nums != b.nums) return a.nums < b.nums;
return a.rootID < b.rootID;
}
int main(){
scanf("%d", &n);
for(int i = 0; i < 10005; ++i) father[i] = i;
int id, k, score;
for(int i = 0; i < n; ++i){
scanf("%d %d", &id, &k);
valid[id] = true;
for(int j = 0; j < k; ++j){
int tmp;
scanf("%d", &tmp);
valid[tmp] = true;
Union(id, tmp);
}
scanf("%d", &score);
scores[id] = score;
}
for(int i = 0; i < 10000; ++i){
if(!valid[i]) continue;
int r = findFather(i);
if(!vis[r]){
vis[r] = true;
position[r] = schools.size();
schools.emplace_back(r, 1, scores[i]);
}
else{
int pos = position[r];
schools[pos].nums++;
schools[pos].scoreSum += scores[i];
}
}
sort(schools.begin(), schools.end(), cmp);
printf("%d\n", schools.size());
for(int i = 0; i < schools.size(); ++ i)
printf("%04d %d %d\n", schools[i].rootID, schools[i].nums, schools[i].scoreSum);
return 0;
}