其实巨水...然而 不用scanf prinf 根本过不了.....真无聊
第一版代码有点问题 效率不高 主要是考虑到这个家族有可能一开始就是个森林 不是从树里分出去的
实际上数据点还是一棵树 然后变成的森林 这样的话只要三个数组就可以了
alive记录是否活着
sons记录每个人的子节点个数
father记录每个人的父节点 可以根据alive[father[x]]判断x是否是一个树的根节点
cnt 维护家族数目
每次死人的时候
判断死的人是某个树的根节点还是只是一个叶子节点 就可以了
#include <iostream> #include <vector> #include <algorithm> #include <cstdio> using namespace std; const int maxN = 200000+10; int N; int father[maxN] = {0}; //记录每个人的父亲是谁 bool alive[maxN] = {false}; //记录是否活着 int sons[maxN]={0};//记录儿子个数 void init(){ cin>>N; } int cnt = 1;//家族数目 void build(){ for (int i = 0; i < N; ++i){ char op; op = getchar(); while(op!='B' and op!='D'){ op = getchar(); } while (op != 'B' && op != 'D') scanf("%c",&op); int x , y; switch(op){ case 'B': scanf("%d %d",&x,&y); if(!alive[x]) sons[x] = 0; father[y] = x; //y的爸爸是x alive[x] = alive[y] = true; //他俩都活着 sons[x]++; break; case 'D': scanf("%d",&x); alive[x] = false; if(!alive[father[x]]) //已经是根节点了 爸爸死了 cnt--; else sons[father[x]]--; cnt += sons[x]; // cout<<cnt<<endl; printf("%d ", cnt); break; } } } int main(int argc, char const *argv[]) { init(); build(); return 0; }