代码随想录Day55|108. 冗余连接、109. 冗余连接II
目录
- 108. 冗余连接
- 解题思路
- 解法
- 109. 冗余连接II
- 解题思路
- 解法
- 今日总结
108. 冗余连接
题目链接:KamaCoder
文章讲解:代码随想录
视频讲解:bilibili
解题思路
本题主要是要将问题转化为集合问题,当再次遇到的一条边的两个节点均在集合中,说明会形成环,那么最先遇到的这条边就是需要输出的结果。
解法
#include <iostream>
#include <vector>
using namespace std;vector<int> father(1005, 0);void init(int n){for(int i=0; i<=n; i++)father[i] = i;
}int find(int u){return u == father[u] ? u : father[u] = find(father[u]);
}bool isSame(int u, int v){u = find(u);v = find(v);return u == v;
}void join(int u, int v){u = find(u);v = find(v);if(u == v) return ;father[v] = u;
}int main(){int n;cin >> n;int s, t;bool flag = true;init(n);for(int i=0; i<n; i++){int u, v;cin >> u >> v;if(isSame(u, v) && flag){s = u;t = v;flag = false;}join(u, v);}cout << s << ' ' << t << endl;return 0;
}
- 时间复杂度:O(n)O(n)O(n)
- 空间复杂度:O(n)O(n)O(n)
109. 冗余连接II
题目链接:KamaCoder
文章讲解:代码随想录
视频讲解:bilibili
解题思路
相比上一题会复杂一些,主要是题目的分析部分,由于仅仅删去一条边就能成为有向树,因此每个点的入度最多为2,也可能存在成环的情况,那么这里用于判断是否成环的部分就用到了并查集。对于存在入度为2的点的情况,并查集用于判断删去的边是否能让其称为有向树(一开始因为成环所以不是有向树),否则,则直接用并查集找第一条让有向树成环的边输出即可。
解法
#include <iostream>
#include <vector>
using namespace std;void dfs(int node, int n, const vector<vector<int>>& link, vector<bool>& visited){visited[node] = true;for(int j=1; j<=n; j++){if(link[node][j] && !visited[j]){dfs(j, n, link, visited);}}return ;
}int main(){int n, k;cin >> n >> k;if(k < n){cout << -1 << endl;return 0;}vector<vector<int>> link(n+1, vector<int>(n+1, 0));vector<bool> visited(n+1, false);for(int i=0; i<k; i++){int x, y;cin >> x >> y;link[x][y] = 1;}dfs(1, n, link, visited);for(int i=1; i<=n; i++){if(!visited[i]){cout << -1 << endl;return 0; }}cout << 1 << endl;return 0; }
- 时间复杂度:O(n)O(n)O(n)
- 空间复杂度:O(n)O(n)O(n)
今日总结
补卡中()
