算法笔记/USACO Guide GOLD金组Graphs并查集Disjoint Set Union

是什么

并查集 (DSU) 数据结构能够向图添加边并测试图的两个顶点是否相连。它将两个集合合并,再询问两个元素是否在一个集合当中。

复制代码
以下是 DSU 的实现。它利用从小到大合并和路径压缩快速执行并集查找。由于真实实践非常简单,他可以用来代替用于计算连接组件的 DFS。
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

class DisjointSets {
  private:
	vector<int> parents;
	vector<int> sizes;

  public:
	DisjointSets(int size) : parents(size), sizes(size, 1) {
		for (int i = 0; i < size; i++) { parents[i] = i; }
	}

	/** @return the "representative" node in x's component */
	int find(int x) { return parents[x] == x ? x : (parents[x] = find(parents[x])); }

	/** @return whether the merge changed connectivity */
	bool unite(int x, int y) {
		int x_root = find(x);
		int y_root = find(y);
		if (x_root == y_root) { return false; }

		if (sizes[x_root] < sizes[y_root]) { swap(x_root, y_root); }
		sizes[x_root] += sizes[y_root];
		parents[y_root] = x_root;
		return true;
	}

	/** @return whether x and y are in the same connected component */
	bool connected(int x, int y) { return find(x) == find(y); }
};

Topological Sort 拓扑排序

复制代码
有向图由只能沿一个方向遍历的边组成。此外,非循环图定义了一种不包含环的图,因此,它无法遍历一条或多条边并返回到开始的节点。将这些定义放在一起,有向无环图(有时缩写为 DAG)是一种具有只能在一个方向上遍历的边并且不包含环的图。

一个拓扑排序的一个有向无环图是其顶点的线性排序,使得对于每个有向边u到v从顶点u到顶点 v,序列中u会出现在v之前。

cpp 复制代码
#include <algorithm>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

vector<int> top_sort;
vector<vector<int>> graph;
vector<bool> visited;

void dfs(int node) {
	for (int next : graph[node]) {
		if (!visited[next]) {
			visited[next] = true;
			dfs(next);
		}
	}
	top_sort.push_back(node);
}

int main() {
	int n, m;  // The number of nodes and edges respectively
	std::cin >> n >> m;

	graph = vector<vector<int>>(n);
	for (int i = 0; i < m; i++) {
		int a, b;
		std::cin >> a >> b;
		graph[a - 1].push_back(b - 1);
	}

	visited = vector<bool>(n);
	for (int i = 0; i < n; i++) {
		if (!visited[i]) {
			visited[i] = true;
			dfs(i);
		}
	}
	std::reverse(top_sort.begin(), top_sort.end());

	vector<int> ind(n);
	for (int i = 0; i < n; i++) { ind[top_sort[i]] = i; }

	// Check if the topological sort is valid
	bool valid = true;
	for (int i = 0; i < n; i++) {
		for (int j : graph[i]) {
			if (ind[j] <= ind[i]) {
				valid = false;
				goto answer;
			}
		}
	}
answer:;

	if (valid) {
		for (int i = 0; i < n - 1; i++) { cout << top_sort[i] + 1 << ' '; }
		cout << top_sort.back() + 1 << endl;
	} else {
		cout << "IMPOSSIBLE" << endl;
	}
}
相关推荐
强哥聊算力2 小时前
《算力江湖·英伟达传奇》第七集:ChatGPT出现前夜,英伟达发生了什么?
服务器·人工智能·算法·ai·chatgpt·gpu算力
ACP广源盛139246256734 小时前
硬件选型笔记:国产 PCIe Gen2.1 交换芯片 IX6024@ACP,工控与存量设备国产化改造方案评估
笔记·硬件架构·硬件工程·pcie·国产芯片
2603_965148115 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
文人sec5 小时前
SQL基础入门笔记 | 从零基础到掌握核心查询语句
数据库·笔记·sql
虹科数字化与AR5 小时前
电力巡检AR眼镜怎么选?重量、防护、续航、摄像头与佩戴方式
经验分享·增强现实·电力巡检
Navigator_Z6 小时前
LeetCode //C - 1289. Minimum Falling Path Sum II
c语言·算法·leetcode
CCblandy6 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
摇滚侠7 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
kaixin_啊啊7 小时前
【用于更准确 G×E 基因组预测的大规模作物数据集与基于深度学习的多模态融合框架】论文学习
人工智能·深度学习·学习
xier_ran7 小时前
【infra之路】AI 编译器学习笔记(六):重拾 C++——lambda 与 MLIR 中的回调
c++·笔记·学习