第八屆藍橋杯決賽之發現環 發現並輸出環

2021-08-19 20:08:37 字數 1615 閱讀 5930

小明的實驗室有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

輸入保證合法。

輸出----

按從小到大的順序輸出在環路上的電腦的編號,中間由乙個空格分隔。

樣例輸入:

51 2

3 12 4

2 55 3

樣例輸出:

1 2 3 5

題目分析:眾所周知tarjan

但是利用並查集加深搜也可以做到

如果在加邊的過程中,邊的兩個點的集合不是乙個集合的話,那麼說明這個邊是不在環上的有可能連線兩個點,有可能連線兩個聯通圖,有可能連線乙個點和乙個聯通圖

如果邊上的兩個端點是屬於乙個點集,那就是這條邊連線是乙個聯通圖上的兩個點,那麼這條邊一定是一造成環,那麼記錄這兩個點,那麼並且不要把這這條邊加入到原圖中,以便於深搜遍歷最大的路徑,也就是這個環

翠花,上**~

#include#include#include#includeusing namespace std;

#define maxn 100010//定義最大的資料規模

int vis[maxn];//訪問標記陣列

setr;//儲存環的下邊,set自動從小到大排序

int pre[maxn];//並查集前驅陣列

vectorm[maxn];//鄰接表

int find(int x)//路徑壓縮並返回集合父節點

return x;

}bool dfs(int s,int e)//深搜

vis[s]=1;//訪問標記1

for(int i=0;i>n;

for(int i=1;i<=n;i++)

pre[i]=i;

memset(vis,0,sizeof(vis));//初始化

int to;

int from=to=0;

for(int i=0;i>a>>b;

if(find(a)!=find(b))//如果該邊的兩個端點不是乙個集合,將該邊加入鄰接表並且放入乙個集合

else //if(from>0)//如果是乙個集合那麼就說明這兩個點是環的點,標記為環的起點和終點,並且從真正的圖中拆掉該邊不加入鄰接表

}dfs(from,to);//從from到to

set::iterator it=r.begin();

for(;it!=r.end();it++)

}

第八屆藍橋杯決賽 發現並輸出環

解題演算法 並查集 向上找祖先 大體思路 先用並查集查詢u v兩個點的祖先是不是同乙個 1 如果不是則合併兩棵樹。2 如果是則表示現在能夠構成環,根據u,v兩個點分別向上查詢其到祖先的路徑,在遍歷兩條路徑,當有公共節點的時候就表示u,v兩個點的最近公共祖先,也是構成環的最開始的節點,從這裡開始將兩條...

第八屆藍橋杯決賽發現環 並查集 DFS

小明的實驗室有n臺電腦,編號1 n。原本這n臺電腦之間有n 1條資料鏈結相連,恰好構成乙個樹形網路。在樹形網路上,任意兩台電腦之間有唯一的路徑相連。不過在最近一次維護網路時,管理員誤操作使得某兩台電腦之間增加了一條資料鏈結,於是網路中出現了環路。環路上的電腦由於兩兩之間不再是只有一條路徑,使得這些電...

第八屆藍橋杯決賽 發現環 dfs 並查集

小明的實驗室有n臺電腦,編號1 n。原本這n臺電腦之間有n 1條資料鏈結相連,恰好構成乙個樹形網路。在樹形網路上,任意兩台電腦之間有唯一的路徑相連。不過在最近一次維護網路時,管理員誤操作使得某兩台電腦之間增加了一條資料鏈結,於是網路中出現了環路。環路上的電腦由於兩兩之間不再是只有一條路徑,使得這些電...