108.冗余連接
題目鏈接:108. 冗余的邊
文章講解:代碼隨想錄
思路:
題意隱含
只有一個冗余邊
#include <iostream>
#include <vector>
using namespace std;
int n=1001;
vector<int>father(n,0);void init(){for(int i=0;i<n;i++){father[i]=i;}
}
int find(int x){if(father[x]==x) return x;else return father[x]=find(father[x]);
}void join(int u, int v){u=find(u);v=find(v);if(u==v) return;father[v]=u;
}bool isSame(int u,int v){u=find(u);v=find(v);return u==v;
}int main(){int n;cin>>n;init();for(int i=0;i<n;i++){int s,t;cin>>s>>t;if(isSame(s,t)){ //s跟t是否連同 已經連通的話說明當前邊冗余cout<<s<<' '<<t<<endl;return 0;}else{join(s,t); }}
}
?
109.冗余連接II
題目鏈接:109. 冗余的邊II
文章講解:代碼隨想錄
根據邊的入度來考慮
情況1: 存在入度為2的節點
說明這個節點存在冗余的邊(存在兩個父節點)
此處需要判斷刪除哪條邊?
情況2:不存在入度為2的節點 此時存在環對于存在環
應該找出哪條邊使得構成環? ? 可以通過并查集來找
#include <iostream>
#include <vector>
using namespace std;int n=1001;
vector<int>father(n,0);
void init(){for(int i=0;i<n;i++){father[i]=i;}
}
int find(int x){if(father[x]==x)return x;else return father[x]=find(father[x]);
}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;
}bool isTreeAfterRemoveEdge(vector<vector<int>>edges,int deleteEdge){init();for(int i=0;i<edges.size();i++){if(i==deleteEdge) continue;if(isSame(edges[i][0],edges[i][1])){return false;}else{join(edges[i][0],edges[i][1]);}}return true;
}int getRemoveEdge(vector<vector<int>>edges){init();for(int i=0;i<edges.size();i++){if(isSame(edges[i][0],edges[i][1])){return i;}else{join(edges[i][0],edges[i][1]);}}return -1;
}int main(){int n;cin>>n;vector<vector<int>>edges;vector<int>inDegree(n+1,0);for(int i=0;i<n;i++){int s,t;cin>>s>>t;inDegree[t]++;edges.push_back({s,t});}vector<int>vec; //記錄入度為2的邊(如果有的話就兩條邊)for(int i=n-1;i>=0;i--){if(inDegree[edges[i][1]]==2){vec.push_back(i);}}if(vec.size()>0){ //情況1if(isTreeAfterRemoveEdge(edges,vec[0])){cout<<edges[vec[0]][0]<<' '<<edges[vec[0]][1];}else{cout<<edges[vec[1]][0]<<' '<<edges[vec[1]][1];}return 0;}else{ //情況2 有環int ans=getRemoveEdge(edges);if(ans>=0) cout<<edges[ans][0]<<' '<<edges[ans][1];}
}