題目 1841: [藍橋杯][2017年第八屆真題]發現環
時間限制: 1Sec 記憶體限制: 128MB 提交: 1116 解決: 390
題目描述
小明的實驗室有N臺電腦,編號1~N。原本這N臺電腦之間有N-1條資料連結相連,恰好構成一個樹形網路。在樹形網路上,任意兩臺電腦之間有唯一的路徑相連。
不過在最近一次維護網路時,管理員誤操作使得某兩臺電腦之間增加了一條資料連結,於是網路中出現了環路。環路上的電腦由於兩兩之間不再是隻有一條路徑,使得這些電腦上的資料傳輸出現了BUG。
為了恢復正常傳輸。小明需要找到所有在環路上的電腦,你能幫助他嗎?
輸入
第一行包含一個整數N。
以下N行每行兩個整數a和b,表示a和b之間有一條資料連結相連。
對於30%的資料,1 <= N <= 1000
對於100%的資料, 1 <= N <= 100000, 1 <= a, b <= N
輸入保證合法。
輸出
按從小到大的順序輸出在環路上的電腦的編號,中間由一個空格分隔。
樣例輸入
5 1 2 3 1 2 4 2 5 5 3
樣例輸出
1 2 3 5
方法一:
並查集判環+dfs輸出
並查集用來 判斷 環的起始點 和 終止點。
用dfs遍歷圖,當符合要求時 輸出環 即可。
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
using namespace std;
const int inf=0x3fffffff;
const int maxn=100100;
int n;
int start,stop;
int father[maxn];
vector<int> ans;
vector<int> Adj[maxn];
int vis[maxn];
void init(){
for(int i=0;i<maxn;i++)
father[i]=i;
}
int findFather(int x){
if(father[x]==x) return x;
return findFather(father[x]);
}
bool Union(int a,int b){
int fa = findFather(a);
int fb = findFather(b);
if(fa!=fb){
father[fb]=fa;
// cout<<fa<<" "<<fb<<endl;
return true;
}
return false;
}
void dfs(int x){
if(x==stop){
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
return ;
}
int len = Adj[x].size();
for(int i=0;i<len;i++){
if(vis[ Adj[x][i] ] == false){
vis[ Adj[x][i] ] = true;
ans.push_back( Adj[x][i] );
dfs( Adj[x][i] ) ;
ans.pop_back() ;
}
}
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0),cout.tie(0);
init();
cin>>n;
int a,b;
for(int i=0;i<n;i++){
cin>>a>>b;
Adj[a].push_back(b);
Adj[b].push_back(a);
bool flag = Union(a,b);
if( flag == false ){
start = a;
stop = b;
}
}
vis[start]=true;
ans.push_back( start );
dfs( start );
return 0;
}
方法二:
拓撲判環: 本題因為是 樹 + 一條邊 只有一個環 且 度 為 1的點 的 鄰接點 只有一個。
步驟 1. 鄰接表形式記錄圖並記錄每一個頂點的度 2. 度為1的點 和 與其相連的邊 一定不在環上 3.度為1的點 一定只有一個鄰接點 4.如果度為1的點的鄰接點在度數減1後也變成了度為1的點 那麼這個點一定也不在環上 5.在環上的點度都為2.
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
const int inf=0x3fffffff;
const int maxn=100100;
int n;
int d[maxn]={0};
vector<int> Adj[maxn];
bool vis[maxn]={0};
void bfs(){
queue<int> q;
for(int i=1;i<=n;i++){
if(d[i]==1){
q.push(i);
vis[i]=true;
}
}
// while(!q.empty()){
//
// int top = q.front(); q.pop();
//
// int len = Adj[top].size();
//
// for(int i=0;i<len;i++){
//
// int v = Adj[top][i];
//
// if( --d[v] == 1){
//
// q.push(v);
// vis[v]=true;
// }
// }
//
// }
while(!q.empty()){
int top = q.front(); q.pop();
int len = Adj[top].size();
for(int i=0;i<len;i++){
int v = Adj[top][i];
if( --d[v] == 1){
q.push(v);
vis[v]=true;
}
}
}
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0),cout.tie(0);
cin>>n;
int a,b;
for(int i=0;i<n;i++){
cin>>a>>b;
d[a]++;
d[b]++;
Adj[a].push_back(b);
Adj[b].push_back(a);
}
bfs();
int flag=0;
for(int i=1;i<=n;i++){
if(vis[i]==true) continue;
if(flag==0){
flag=1;
}else
cout<<" ";
cout<<i;
}
return 0;
}
相關文章
- 藍橋杯真題
- 藍橋杯第五屆省賽題目及題解
- [藍橋杯][2016年第七屆真題]冰雹數
- 2013年藍橋杯真題
- 藍橋杯真題:純質數
- 藍橋杯省賽真題2013題解
- [藍橋杯][2014年第五屆真題]地宮取寶
- [藍橋杯][2015年第六屆真題] 移動距離
- 藍橋杯題目編號1265
- 2015年藍橋杯六屆省賽大學B組真題
- 【藍橋杯】練習題目彙總
- 藍橋杯 試題 歷屆試題 螞蟻感冒
- 藍橋杯真題之錯誤票據
- 藍橋杯 2014屆真題 地宮取寶 動態規劃解法動態規劃
- 藍橋杯練習系統題目集
- 藍橋杯2019年真題:字尾表示式
- 2017第八屆藍橋杯C/C++ B組省賽第二題 秒解C++
- 藍橋杯-座次問題
- 藍橋杯-日期問題
- 【藍橋杯】試題 歷屆試題 剪格子(python解法+java解法)PythonJava
- 第九屆藍橋杯軟體類省賽 Java B組 題目及解析Java
- 藍橋杯__省賽__第八屆__C/C++__大學A組C++
- 藍橋杯競賽題目:”機器人繁殖“解析及題解機器人
- 藍橋杯全排列專題
- 太陽(藍橋杯14屆)
- 方格分割 二進位制列舉+DFS(2017 第八屆藍橋杯省賽A組 第4題)
- 藍橋杯模擬題——長草問題
- 藍橋杯例題-快速分揀
- 題目 1501: [藍橋杯][演算法提高VIP]分蘋果演算法蘋果
- 第十一屆藍橋杯大賽第二次模擬(軟體類)真題(做題筆記)筆記
- 第十屆藍橋杯C++國賽B組部分題解(假題解)C++
- 2020藍橋杯省賽B組C++(第二場)真題C++
- 藍橋杯15年真題奇妙的數字暴力集合去重
- 藍橋杯第 3 場 演算法季度賽第八題 升級電纜題解演算法
- 發現一個可以練習藍橋杯VIP題目的網址
- 【題解】爬山 藍橋杯2024省B
- 2013藍橋杯題解c++A組C++
- Java藍橋杯14年第五題Java