Blood Cousins Return 解题报告
为了体现我29买的typora的价值,本文用typora编辑
题目链接
[E. Blood Cousins Return](Problem - 246E - Codeforces)
思路
就是裸的(但不是神的)DSU on tree
但是主教练给了个思考方向:bfs序???很合理,深深感觉思路被局限了。
蒟蒻只会看题解,尽管这是一道简单题(我不会dsu)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
#define pii pair<int,int>
vector<pii>q[maxn];//存储问题
struct Node{
string name;
int fa,num;
}node[maxn];
struct Edge{
int v,nxt;
}edge[maxn];
int head[maxn],edgetot;
void add(int u,int v){
// cout<<"add "<<u<<' '<<v<<endl;
edge[++edgetot]=(Edge){v,head[u]};
head[u]=edgetot;
}
int dep[maxn],sz[maxn],son[maxn],ans[maxn];
void dfs1(int u,int fa){
dep[u]=dep[fa]+1;
if(!head[u])sz[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
dfs1(v,u);
if(sz[son[u]]<sz[v])son[u]=v;
sz[u]+=sz[v];
}
}
set<string>name[maxn*2];
int vis[maxn];
void del(int x){
name[dep[x]].clear();
for(int i=head[x];i;i=edge[i].nxt)del(edge[i].v);
}
void add(int x){
// cout<<"add u fa"<<" "<<edge[head[x]].v<<endl;
name[dep[x]].insert(node[x].name);
for(int i=head[x];i;i=edge[i].nxt)add(edge[i].v);
// cout<<"added u fa"<<" "<<x<<endl;
}
void dfs2(int u,int fa){//dsu 探究某深度的个数
vis[u]=1;
for(int i=head[u];i;i=edge[i].nxt){//轻
int v=edge[i].v;
if(v==son[u])continue;
dfs2(v,u);
del(v);
}
if(son[u])dfs2(son[u],u);//重
for(int i=head[u];i;i=edge[i].nxt){
if(edge[i].v!=son[u])add(edge[i].v);//重儿子之前操作了妹清空
}
name[dep[u]].insert(node[u].name);//加进去后统计答案
for(auto i:q[u])ans[i.second]=name[i.first].size();
//[dsu]意义在于不用清空son[u]
}
int main(){
// ios::sync_with_stdio(0),cin.tie(0);
int n,m,k,v,r;
cin>>n;
string s;
for(int i=1;i<=n;++i){
cin>>s>>r;
node[i]=(Node){s,r,i};
add(r,i);
}
for(int i=1;i<=n;++i)if(!dep[i])dfs1(i,0);
cin>>m;
for(int i=1;i<=m;++i){
cin>>v>>k;
q[v].push_back({dep[v]+k,i});
}
for(int i=1;i<=n;++i)
if(!vis[i])dfs2(i,0),del(i);
for(int i=1;i<=m;++i)cout<<ans[i]<<"\n" ;
return 0;
}
代码有点丑,不过好在代码不长

浙公网安备 33010602011771号