并查集P5836 [USACO19DEC] Milk Visits S
题目传送门:[https://www.luogu.com.cn/problem/P5836](P5836 [USACO19DEC] Milk Visits S)
我的做法是并查集:对于某个节点的子节点,如果子节点和父节点的类型相同,把子节点合并到父节点的集合之中,否则自己独立一个集合。
在这个思路之上往下dfs。
处理完之后对于每个查询find他们的祖先:
如果他们不在一个集合内的话,那肯定是可以满足两种情况的;如果在一个集合内判断这个集合是否和我要的类型相同。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
int n,m;
vector<int>e[N];
int fa[N],w[N],nw[N];
int cnt = 0;
int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void dfs(int u,int f)
{
for(int v : e[u])
{
if(v == f)continue;
if(w[v] == w[find(u)])fa[v] = fa[u];
else nw[fa[v]] = w[v];
dfs(v,u);
}
}
int main()
{
cin>>n>>m;
for(int i = 1 ; i <= n ; ++i)
{
char c;cin>>c;
w[i] = (c == 'H');
fa[i] = i;
// cout<<"w[i]: "<<w[i]<<endl;
}
for(int i = 1 ; i < n ; ++i)
{
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
nw[1] = w[1];
dfs(1,0);
while(m--)
{
int u,v;
char c;
cin>>u>>v>>c;
int now = (c == 'H');
int a = find(u),b = find(v);
if(a != b)cout<<1;
else{
if(nw[a] == now)cout<<1;
else cout<<0;
}
}
// cout<<endl;
// for(int i = 1 ; i <= n ; ++i)
// cout<<find(i)<<" \n"[i == n];
return 0;
}
浙公网安备 33010602011771号