基础树上问题 P5836 [USACO19DEC]Milk Visits S【并查集进行图的染色】
题目
https://www.luogu.com.cn/problem/P5836
分析
由于每个点的颜色选择范围都是两种,所以我们可以使用并查集来记录同一种颜色的连通块。
刚开始我的思路比较歪,只是单纯的考虑怎样能记录可以使朋友开心,后来想到可以考虑在怎样的情况下不能使朋友开心
具体看代码
代码
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; #define maxn 100010 #define maxm 100010 int father[maxn], answer[maxn],ranks[maxn]; char mark[maxn]; int cnt = 0; int n, m; int find(int x) { if (father[x] == x) return x; return father[x] = find(father[x]); } void merge(int x,int y) { int a = find(x); int b = find(y); if (a == b)return; if (ranks[a] > ranks[b])father[b] = a; else { father[a] = b; if (ranks[a] == ranks[b])ranks[b]++; } } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> mark[i]; father[i] = i; } for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b;//这里是思路的核心 if (mark[a] == mark[b])merge(a,b); //这里就是使用并查集来记录连通块,因为a b一定是相邻的,而且从农场 A到农场 B之间的唯一路径行走,所以我们只需要merge(a,b)就可以记录了 } for (int i = 1; i <= m; i++) { int a, b; char c; cin >> a >> b; cin >> c; if (find(a) == find(b) && mark[a] != c)answer[cnt++] = 0;//满足这种情况的才不能是朋友开心,其余的都可以 else answer[cnt++] = 1; } for (int i = 0; i < cnt; i++) printf("%d", answer[i]); } //6 1 //HHGHGH //1 2 //2 3 //2 4 //1 5 //3 6 //2 6 G