白魔法师 & maki和tree - 并查集统计树上信息
都是并查集来求的
有一棵树,树上每一个点有一个颜色,白色或者黑色,然后可以把一个黑色变成白色。求白色的最大连通块
把每一个黑色点看成并查集的根节点,然后与这个黑色点连通的白色点都是这个并查集里面的点
那么并查集最大值就是答案
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
std::vector<int> G[N];
char s[N];
int fa[N], rak[N], siz[N];
int find(int x){
return fa[x] == x ? x : find(fa[x]);
}
void unit(int x, int y){
x = find(x), y = find(y);
if(x != y){
if(rak[x] < rak[y]){
fa[x] = y;
rak[y] += rak[x] + 1;
}else{
fa[y] = x;
rak[x] += rak[y] + 1;
}
}
}
int main(){
int n;
scanf("%d", &n);
scanf("%s", s + 1);
for(int i = 1; i <= n; i++)fa[i] = i;
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
if(s[u] == s[v] && s[v] == 'W')unit(u, v);
}
for(int i = 1; i <= n; i++)
if(s[i] == 'W')siz[i] = rak[find(i)] + 1;
int ans = 0;
for(int i = 1; i <= n; i++){
if(s[i] == 'B'){
int sum = 1;
for(int j = 0; j < G[i].size(); j++){
if(s[G[i][j]] == 'W')sum += siz[G[i][j]];
}
ans = max(ans, sum);
}
}
printf("%d\n", ans == 0 ? n : ans);
return 0;
}
maki和tree是求路径有多少条
我的题解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
char s[maxn];
std::vector<int> G[maxn];
ll sum,t1,t2,ans;
void dfs(int p,int fa){
if(s[p] == 'B')return;
sum++;
for(int i = 0; i < G[p].size(); i++)
if(G[p][i] != fa)dfs(G[p][i],p);
}
int main(){
int n = read();
scanf("%s",s+1);
for(int i = 1; i < n; i++){
int x,y;
x = read(),y = read();
G[x].push_back(y);
G[y].push_back(x);
}
for(int i = 1; i <= n; i++){
t1 = 0,t2 = 0;//t1黑点的所有点延续下去,连续白色的个数
if(s[i] == 'B'){
for(int j = 0; j < G[i].size(); j++){
sum = 0;//表示与黑色点连接的一个点延续下去,连续白色的个数
dfs(G[i][j],G[i][j]);
ans += sum;
t1 += sum;
t2 += sum * sum;
}
ans += (t1 * t1 - t2)/2;
}
}
printf("%lld\n",ans);
return 0;
}
I‘m Stein, welcome to my blog