1 条题解
-
0
因为Monster是懒狗,所以题解也很水。树是一个连通且无环的无向图,在树中多了一条附加的边之后就会出现环,因此要删去的的边即为导致环出现的边。
可以通过并查集寻找这条边。初始时,每个节点都属于不同的连通分量。遍历每一条边,判断这条边连接的两个顶点是否属于相同的连通分量。
如果两个顶点属于不同的连通分量,则说明在遍历到当前的边之前,这两个顶点之间不连通,因此当前的边不会导致环出现,合并这两个顶点的连通分量。
如果两个顶点属于相同的连通分量,则说明在遍历到当前的边之前,这两个顶点之间已经连通,因此当前的边导致环出现,将当前的边作为答案返回。
时间复杂度:,其中是图中的节点个数。需要遍历图中的条边,对于每条边,需要对两个节点查找祖先,如果两个节点的祖先不同则需要进行合并,需要进行 2 次查找和最多 1 次合并。一共需要进行次查找和最多次合并,因此总时间复杂度是。这里的并查集使用了路径压缩,但是没有使用按秩合并,最坏情况下的时间复杂度是,平均情况下的时间复杂度依然是,其中为阿克曼函数的反函数,可以认为是一个很小的常数。
空间复杂度:,其中是图中的节点个数。使用数组记录每个节点的祖先。
代码
#include <bits/stdc++.h> using namespace std; int find(int x, vector<int> &fa) { return x == fa[x] ? x : fa[x] = find(fa[x], fa); } int main() { int n, x, y; cin >> n; vector<int> fa(n + 1, 0); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 0; i < n; i++) { cin >> x >> y; if (find(x, fa) != find(y, fa)) fa[find(x, fa)] = find(y, fa); else { cout << x << " " << y << endl; break; } } return 0; }
- 1
信息
- ID
- 257
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 48
- 已通过
- 17
- 上传者