本文主要是介绍代码随想录算法训练营第五十六天 | 图论part06,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
108. 冗余连接
#include <iostream>
#include <vector>using namespace std;void init(vector<int> &father) {for (int i = 0; i < father.size(); ++i) {father[i] = i;}
}int find(vector<int>& father, int u) {if (father[u] == u) return u;return father[u] = find(father, father[u]);
}int isSame(vector<int>& father, int u, int v) {u = find(father, u);v = find(father, v);return u == v;
}void join(vector<int>& father, int u, int v) {u = find(father, u);v = find(father, v);if (u == v) return;father[v] = u;
}
int main()
{int n, u, v, resultu, resultv;cin >> n;vector<int> father(n + 1, 0);init(father);for (int i = 0; i < n; ++i) {cin >> u >> v;if (isSame(father, u, v)) {resultu = u;resultv = v;}elsejoin(father, u, v);}cout << resultu << " " << resultv << endl;return 0;
}
109. 冗余连接II
关键是要能够分出两种情况:
- 是不是存在入度为2的点,然后判断哪一条边去掉,还是连通的。在这里也有两种情况,一种是直接删除最后一个边,一种是会形成环。
- 是不是存在环
#include <iostream>
#include <vector>using namespace std;void init(vector<int>& father) {for (int i = 0; i < father.size(); ++i) {father[i] = i;}
}int find(vector<int>& father, int u) {if (father[u] == u) return u;return father[u] = find(father, father[u]);
}int isSame(vector<int>& father, int u, int v) {u = find(father, u);v = find(father, v);return u == v;
}void join(vector<int>& father, int u, int v) {u = find(father, u);v = find(father, v);if (u == v) return;father[v] = u;
}bool isTreeAfterRemove(vector<int>& father, const vector<vector<int>>& edges, int deleteEdge) {init(father);for (int i = 0; i < edges.size(); ++i) {if (i == deleteEdge) continue;if (isSame(father, edges[i][0], edges[i][1]))return false;join(father, edges[i][0], edges[i][1]);}return true;
}void getRemoveEdge(vector<int>& father, const vector<vector<int>>& edges) {init(father);for (vector<int> pair : edges) {if (isSame(father, pair[0], pair[1])) {cout << pair[0] << " " << pair[1] << endl;return;}join(father, pair[0], pair[1]);}
}int main()
{int n, u, v;cin >> n;vector<int> father(n + 1, 0);vector<vector<int>> edges;vector<int> inDegrees(n + 1, 0);for (int i = 0; i < n; ++i) {cin >> u >> v;inDegrees[v]++;edges.emplace_back(vector<int>{u, v});}vector<int> vec;for (int i = n - 1; i >= 0; --i) {if (inDegrees[edges[i][1]] == 2)vec.push_back(i);}if (vec.size() > 0) {if (isTreeAfterRemove(father, edges, vec[0])) {cout << edges[vec[0]][0] << " " << edges[vec[0]][1] << endl;}elsecout << edges[vec[1]][0] << " " << edges[vec[1]][1] << endl;return 0;}getRemoveEdge(father, edges);return 0;
}
这篇关于代码随想录算法训练营第五十六天 | 图论part06的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!