684.冗餘連線
題幹
樹可以看成是一個連通且 無環 的 無向 圖。
給定往一棵 n 個節點 (節點值 1~n) 的樹中新增一條邊後的圖。新增的邊的兩個頂點包含在 1 到 n 中間,且這條附加的邊不屬於樹中已存在的邊。圖的資訊記錄於長度為 n 的二維陣列 edges ,edges[i] = [ai, bi] 表示圖中在 ai 和 bi 之間存在一條邊。
請找出一條可以刪去的邊,刪除後可使得剩餘部分是一個有著 n 個節點的樹。如果有多個答案,則返回陣列 edges 中最後出現的那個。
輸入: edges = [ [1,2], [1,3], [2,3] ]
輸出: [2,3]
輸入: edges = [ [1,2], [2,3], [3,4], [1,4], [1,5] ]
輸出: [1,4]
思路
對於一個包含n個節點的圖,至少需要n-1條邊才能使圖連線起來,本題中共有n條邊,n個節點,那麼出現的第一條使得圖成環的邊就是最後一條使得圖成環的邊,即該邊就是答案。
在無環圖中考慮連通性使用並查集,在有向圖中考慮依賴性使用dfs、bfs或拓撲排序。
vector<int> findRedundantConnection(vector<vector<int>>& edges) {
int len=edges.size();
vector<int> p(len+1);
for(int i=1; i<=len; ++i)
{
p[i]=i;
}
for(auto &edge : edges)
{
int v1=edge.front(), v2=edge.back();
//查詢兩個節點v1和v2是否屬於同一個集合
if(Find(p,v1)!=Find(p,v2))
{
Union(p,v1,v2);
}
else
{
return edge;
}
}
return vector<int>{};
}
int Find(vector<int>& p, int index)
{
//如果index的parent不是index,說明index已經歸到某個集合中,繼續查詢index的parent
//最頂層的index的parent是其本身
if(p[index]!=index)
{
p[index]=Find(p,p[index]);
}
return p[index];
}
void Union(vector<int> &p, int v1, int v2)
{
//定義聯合為將v1所在的集合的父節點設定為v2所在集合的父節點,這樣兩個集合就連線了
p[Find(p,v1)]=Find(p,v2);
}