E. DFS Trees
树上差分
/*input
10 11
1 2
2 5
3 4
4 2
8 1
4 5
10 5
9 5
8 2
5 7
4 6
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef pair<int,int> pii;
int fa[N],ds[N];
int len[N],xl[N],num[N];
bool in[N];
vector<int> eage1[N],eage0[N];
int get(int x){
if(x!=fa[x]) return fa[x]=get(fa[x]);
return x;
}
void link(int x,int y){
int i=get(x);
int j=get(y);
if(ds[i]>ds[j]) swap(i,j);
fa[i]=j;
ds[j]+=ds[i];
}
void dfs1(int root,int fa){
in[root]=1;
len[root]=len[fa]+1;
xl[len[root]]=root;
for(auto i:eage0[root]){
int node=i;
if(!in[node]){
if(!len[node])
num[root]++,num[node]++;
}
else{
num[1]++,num[node]--,
num[xl[len[node]+1]]--;
}
}
for(auto i:eage1[root]){
int node=i;
if(node!=fa)
dfs1(node,root);
}
in[root]=0;
}
void dfs2(int root,int fa){
num[root]+=num[fa];
for(auto i:eage1[root]){
int node=i;
if(node!=fa)
dfs2(node,root);
}
}
void solve(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
ds[i]=1;
fa[i]=i;
num[i]=0;
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
if(get(x)!=get(y)){
link(x,y);
eage1[x].push_back(y);
eage1[y].push_back(x);
}
else{
eage0[x].push_back(y);
eage0[y].push_back(x);
}
}
dfs1(1,0);
dfs2(1,0);
for(int i=1;i<=n;i++){
if(num[i]==m-n+1) cout<<1;
else cout<<0;
}
cout<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t=1;
while(t--) solve();
}
这篇博客主要介绍了树上差分的概念,并通过C++代码展示了如何使用并查集来解决相关问题。程序中定义了`get`、`link`函数用于并查集操作,`dfs1`和`dfs2`进行深度优先搜索,计算节点的数值。最后,程序读取输入数据,处理边的连接,并输出每个节点的树上差分结果。
329

被折叠的 条评论
为什么被折叠?



