11045: 【原1045】二哥的家族
题目
题目描述
author: oldherl 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1045
Description
二哥的家族(简称二家)有详细记录家谱的传统,当然和其他的家谱一样里面是只记录雄性成员的。
维护家谱是一件很麻烦的事。二家不时有人出生或死去,都需要及时反映在家谱上。
当一个二家的(雄性的)人出生时,就要写在他的父亲的下面。当一个二家的(雄性的)人死去时,他的儿子们(如果有的话)就会带着各自的子孙们(如果有的话)离开他们的祖父/叔叔/大爷们,各自成为一个新的家。
没出生的人和死人是不能生育后代的(废话),而且不允许孩子出生时父亲已经死去这种情况(别问我为啥,这也是二家的规定)。
春节时每家都要派出一个人参加“二家代表大会”(简称二会),所以就需要知道二家此时有几个家。
初始时二家只有一个人(也就是二哥)。
Input Format
二哥的编号为1
第 1 行:一个整数 N 表示下面的行数。
第 2..N+1 行:每行是以下三种操作之一:
B x y 其中x和y是两个整数,表示编号为x的人(保证存在)有了一个编号为y的孩子
D x 其中x是一个整数,表示编号为x的人(保证存在)死去了
Output Format
对于每一个D操作,输出一个整数表示这个人死了以后二家有几个家。
Hint
对100%的数据,3 <= N <= 200000。
题目中出现的所有数均为不超过 200000 的正整数。
同一时间活着的人的编号不会重复。
Sample Input
7
B 1 2
B 1 3
D 1
B 2 4
B 4 5
B 2 6
D 4
Sample Output
2
3
FineArtz's solution
/* 二哥的家族 */
#include <iostream>
using namespace std;
bool b[200005] = {0};
int father[200005] = {0}, son[200005] = {0};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, cnt = 1;
cin >> n;
b[1] = true;
while (n--){
char ch;
cin >> ch;
if (ch == 'B'){
int x, y;
cin >> x >> y;
father[y] = x;
++son[x];
b[y] = true;
}
else if (ch == 'D'){
int x;
cin >> x;
if (b[father[x]]){
cnt += son[x];
--son[father[x]];
}
else
cnt += son[x] - 1;
b[x] = false;
son[x] = 0;
cout << cnt << '\n';
}
}
return 0;
}
ligongzzz's solution
#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>
using namespace std;
class person {
public:
int parent = 0, childnum = 0;
bool status = true;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
unordered_map<int, int> person_map;
vector<person> vdata;
int total_cnt = 1, ans = 1;
//Init
person fiperson;
fiperson.status = false;
vdata.emplace_back(fiperson);
fiperson.status = true;
vdata.emplace_back(fiperson);
person_map.insert(make_pair(1, 1));
for (; n; --n) {
string ch;
cin >> ch;
if (ch == "B") {
int x, y;
cin >> x >> y;
person tmp;
tmp.parent = person_map[x];
vdata[person_map[x]].childnum++;
vdata.emplace_back(tmp);
person_map.insert(make_pair(y, ++total_cnt));
}
else if (ch == "D") {
int x;
cin >> x;
vdata[person_map[x]].status = false;
if (!vdata[person_map[x]].parent || !vdata[vdata[person_map[x]].parent].status) {
ans += vdata[person_map[x]].childnum - 1;
}
else {
--vdata[vdata[person_map[x]].parent].childnum;
ans += vdata[person_map[x]].childnum;
}
person_map.erase(x);
cout << ans << "\n";
}
}
return 0;
}
WashSwang's solution
#include <iostream>
#include <cstdio>
using namespace std;
int total,fa[300000],son[300000],n,x,y;
char c;
bool die[300000];
int main() {
fa[1]=0;
die[0]=true;
total=1;
scanf("%d",&n);
for (int i=0;i<n;++i){
c=0;
while (c!='B'&&c!='D') c=getchar();
if (c=='B'){
scanf("%d%d",&x,&y);
fa[y]=x;
son[x]++;
}
if (c=='D'){
scanf("%d",&x);
die[x]=true;
if (die[fa[x]])
total+=son[x]-1;
else {
son[fa[x]]-=1;
total += son[x];
}
son[x]=0;
printf("%d\n",total);
}
}
return 0;
}
yyong119's solution
#include <iostream>
#include <cstring>
#include <cstdio>
int father[200001], son[200001];
bool alive[200001];
char Data;
int n, i, num, a, b;
using namespace std;
void Solvedead(int Dindex) {
if (alive[father[Dindex]] == false) {
num += son[Dindex] - 1;
} else {
son[father[Dindex]] -= 1;
num += son[Dindex];
}
father[Dindex] = Dindex;
alive[Dindex] = false;
printf("%d\n", num);
}
int main() {
scanf("%d", &n);
num = 1;
father[1] = 1;
memset(alive, true, sizeof(alive));
for (i = 1; i <= n; i++) {
scanf("%s", &Data);
if (Data == 'B') {
scanf("%d%d", &a, &b);
father[b] = a;
son[a] += 1;
}
else {
scanf("%d", &a);
Solvedead(a);
}
}
return 0;
}