📅  最后修改于: 2023-12-03 15:42:22.322000             🧑  作者: Mango
这是一道关于图论的题目,题目描述为:给定一张无向图,求其中的一组基。
在图论中,基的定义就是一组互相不连通的边,可以用这些边来覆盖整张图,也就是说每条边都至少有一个端点被基中的某一条边覆盖到了。
为了求一组基,我们可以使用 Tarjan 算法。该算法是基于深度优先搜索(DFS)的,其基本思路是先求出整张图的割边,再求出割边之外的基。
在有向图中,Tarjan 算法的时间复杂度为 O(E+V),其中 E 表示边数,V 表示顶点数。
下面是使用 C++ 实现的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e5+5, MAXM = 1e5+5;
int head[MAXN], nxt[MAXM], to[MAXM], dfn[MAXN], low[MAXN], st[MAXN], vis[MAXN];
int cnt, num, top, idx;
void add_edge(int u, int v) {
to[++cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
}
void Tarjan(int u, int fa) {
dfn[u] = low[u] = ++num;
st[++top] = u;
vis[u] = true;
for (int i = head[u]; i; i = nxt[i]) {
int v = to[i];
if (v == fa) continue;
if (!dfn[v]) {
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
idx++;
while (true) {
int x = st[top--];
printf("%d ", x);
if (x == v) break;
}
printf("\n");
}
} else if (vis[v]) {
low[u] = min(low[u], dfn[v]);
}
}
vis[u] = false;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d %d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
Tarjan(1, 0);
while (top) {
printf("%d ", st[top--]);
}
return 0;
}
该算法实现使用了 C++ 语言,可以在任何支持 C++ 的环境中运行。