首页 > 其他分享 >ABC302Ex Ball Collector (可撤销并查集)

ABC302Ex Ball Collector (可撤销并查集)

时间:2024-02-22 21:33:25浏览次数:24  
标签:sz 连通 Ball f1 int ABC302Ex ecnt MAXN Collector

由于博客园存在关站风险,文章以后同步发在 这里,可能会有更好的阅读体验。

首先我们分析一下,如果我们已经知道了要走哪些点,我们可以怎么做。

考虑将 \(a_i,b_i\) 之间连边,发现题目可以被转化为给定一个图,要求对于每条边将其一个顶点染色,问最多能将多少个点染色。

于是我们对于每个连通块分开来考虑。对于一个连通块,注意到我们不能将每个顶点染色当且仅当这个连通块是树,且此时可以染色的定点数量为连通块大小减一,如下:

  1. 如果当前连通块是树,则我们可以固定一个点作为根节点,其余所有非根节点,用它连向父亲的那条边对他进行染色。
  2. 如果当前连通块不是树,则我们可以求出他的一个生成树,以一个在环中的节点作为根节点,以 (1) 的方案将这个连通块除了这个根节点以外的点染色,接下来用这个环上的与根节点连接的非树边将这个根节点染色。

所以问题就被我们转换成了,需要维护每个连通块是否为树,并且维护答案。因为要求最短路径,所以我们可以在给定的树上以节点 \(1\) 为根进行 DFS,于是从 \(1\) 到 \(x\) 的最短路径就是链上的点。问题就进一步转换成:每次需要在图中加入一条边 \(a_i,b_i\),询问有多少个连通块与其中有多少个是树。发现可撤销并查集可以做到:在合并/撤销的时候维护一下每个连通块里的边的数量,最终根据边的数量与点的数量判断是否为树即可。

最终时间复杂度 \(O(n \log n)\),其中 \(\log n\) 是可撤销并查集的复杂度。

const int MAXN = 4e5 + 5;
int n, fa[MAXN], a[MAXN], b[MAXN], sz[MAXN], ecnt[MAXN], now, ans[MAXN];
stack<pair<int, int>> st;
vector<int> T[MAXN];

int find(int x) {
	if (fa[x] == x) return x;
	else return find(fa[x]);
}

void merge(int u, int v) {
	if (sz[v] > sz[u]) swap(u, v);
	st.push(make_pair(u, v));
	fa[v] = u;
	sz[u] += sz[v];
	ecnt[u] += ecnt[v] + 1;
}

void undo() {
	int u = st.top().first, v = st.top().second;
	st.pop();
	fa[v] = v;
	ecnt[u] -= ecnt[v] + 1;
	sz[u] -= sz[v];
}

void dfs(int x, int fat) {
	int f1 = find(a[x]), f2 = find(b[x]);
	bool merged = false;
	int add = 0;
	if (f1 == f2) {
		ecnt[f1]++;
		if (sz[f1] == ecnt[f1]) now++, add = 1;
	}
	else {
		if (!(ecnt[f1] >= sz[f1] && ecnt[f2] >= sz[f2])) {
			now++;
			add = 1;
		}
		merge(f1, f2);
		merged = true;
	}
	if (x != 1) ans[x] = now;
	for (auto u:T[x]) {
		if (u == fat) continue;
		dfs(u, x);
	}
	if (merged) undo();
	else ecnt[f1]--;
	now -= add;
}

void work() {
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i] >> b[i];
	}
	for (int u, v, i = 1; i < n; ++i) {
		cin >> u >> v;
		T[u].push_back(v);
		T[v].push_back(u);
	}
	for (int i = 1; i <= n; i++) fa[i] = i, sz[i] = 1;
	dfs(1, 0);
	for (int i = 2; i <= n; ++i) cout << ans[i] << ' ';
	cout << endl;
}

标签:sz,连通,Ball,f1,int,ABC302Ex,ecnt,MAXN,Collector
From: https://www.cnblogs.com/XiaoQuQu/p/18028270

相关文章

  • [AGC021E] Ball Eat Chameleons 题解
    Description有\(n\)只变色龙,一开始都是蓝色。现在你喂了\(k\)次球,每次指定一只变色龙吃下你指定颜色的球。一只变色龙从蓝色变成红色当且仅当它吃的红球比蓝球多;一只变色龙从红色变成蓝色当且仅当它吃的蓝球比红球多。求最后能使所有变色龙都变成红色的方案数。两个方案......
  • 【可观测性系列】 OpenTelemetry Collector的部署模式分析
    ......
  • Collectors.toMap的暗坑与避免方式
    使用Java的stream中的Collectors可以很方便地做容器间的转换,可以少写很多代码。但是其中有暗含的坑需要注意和避免,本文探讨Collectors.toMap(JDK8版本)。Collectors.toMap可以将一个流转化成Map,常见于需要将List转换成Map以便于进一步操作的场景,比如在通过RPC接口获取一个返回结果......
  • Central Collector Installation · glowroot/glowroot Wiki
    *[glowrootjava简单的轻量的apm工具-荣锋亮-博客园](https://www.cnblogs.com/rongfengliang/p/16230407.html)*[CentralCollectorInstallation·glowroot/glowrootWiki·GitHub](https://github.com/glowroot/glowroot/wiki/Central-Collector-Installation#opt......
  • 小球游戏 -- balls in a line
    ;Ballsinaline;withA-Starpanthfind;2023.6EnableExplicit#wd=65;width#Xc=20#Yc=20#obstruct=1#channel=0#BallsCount=10DeclareModuleLinearlySpacedValueDeclare.fFloat(IncrementID.l,IncrementMax.l,MinValue.f,MaxValue.f)EndDe......
  • F - Usual Color Ball Problems
    F-UsualColorBallProblemsProblemStatementYouaregivenpositiveintegers$N$,$M$,$K$,andasequenceofpositiveintegersoflength$N$,$(C_1,C_2,\ldots,C_N)$.Foreach$r=0,1,2,\ldots,N-1$,printtheanswertothefollowingproblem.......
  • Stream toList不能滥用以及与collect(Collectors.toList())的区别
    StreamtoList()返回的是只读List原则上不可修改,collect(Collectors.toList())默认返回的是ArrayList,可以增删改查1.背景在公司看到开发环境突然发现了UnsupportedOperationException报错,想到了不是自己throw的应该就是操作collection不当。发现的确是同事使用了类似stringL......
  • 初中英语优秀范文100篇-059Let’s Play Basketball-让我们打篮球吧
    PDF格式公众号回复关键字:SHCZFW059记忆树1Playingbasketballhasseveraladvantages.翻译打篮球有很多好处简化记忆好处句子结构主语是"Playingbasketball",表示一种活动。谓语是"has",是第三人称单数形式,表示现在完成时态。宾语是"severaladvantages",是一个名......
  • PostgreSQL 数据库日志收集功能开启-参数 logging_collector 设置
    PostgreSQL数据库默认数据库日志收集功能为关闭,但PostgreSQL官方建议开启该参数,但该参数开启需要配合多个参数才能完成,本节只介绍logging_collector  ,如下一logging_collector(boolean)logging_collector   --是否开启日志收集开关,默认off,推荐onThisparameterenabl......
  • gym103415A Math Ball
    套路生成函数。写出答案的式子,设\(f_i(x)=\sumj^{c_i}x^j\),不难得到答案为:\[[x^W]{1\over1-x}\prod_{i=1}^nf_i(x)\]考虑求\(f_i(x)\)。看到指数上有\(c_i\),想到用斯特林数展开:\[f_i(x)=\sum_{j=0}^{\infty}x^j\sum_{k=0}^{c_i}{c_i\bracek}\binom{j}{k}k!\]\[=\s......