//小希的迷宮
小希的迷宮 這道題是道典型的並查集題,中文題題意就不說了配著圖題意很清楚。
用給你的資料構成乙個無向圖,要我們判斷這個圖有沒有迴路也就是這個圖是不是一棵樹。或者判斷這組資料是構成一棵樹還是乙個森林n個不向交的樹。這就是這道題考察的問題。
條件1、根據資料每兩個資料表示一條邊,每組資料表示這個圖有多少條邊,當他們加入到並查集中,每次合併就是一條邊的合併。並查集中的邊不存在迴路,假如此圖存在迴路則邊數和並查集的合併次數肯定不同。這樣就會判斷出這個圖有沒有迴路。
條件2、根據資料我們得到這個圖里的結點數,根據並查集的性質或者說是屬性,用路徑壓縮的並查集處理後,rank陣列裡存的就是下標所在的樹有多少個結點。如果最原始結點在rank陣列的值與題目所給的資料裡的結點數目相等就證明這是一棵樹或者乙個圖。
條件 1的實現方法: 每讀取一條邊的資料就記錄一下,並查集每次合併再記錄一下,比較兩次記錄結果判斷是否有迴路。
條件 2的實現方法: 用c++ stl模版 set容器來儲存每條邊,根據set容器的性質判斷出這個圖有多少結點。 用有路徑壓縮的並查集find函式找到原始祖先,然後用原始祖先rank陣列的值與set容器存的值進行比較,判斷是否是一棵樹或是森林。
stl set容器
set 容器裡的元素值唯一 。
就是假如存1在乙個set容器中,再存乙個1,在set中存的還是乙個1。不會是兩個1。
標頭檔案 #include
申請命名空間 using namespace std;
定義乙個int型set: ints;
插入乙個元素x:s.insert(x);
容器記憶體了多少個元素:s.size();
#include #include #include #define max 1000002
using namespace std;
int root[max];
int rank[max];
int num;
void init ()
}int find (int x)
void union (int x,int y)
return ;
}int main ()
if (x==-1 && y==-1)
init();
a=x;
num=0;
union(x,y);
int count=1;
s.insert(x);
s.insert(y);
while (scanf ("%d%d",&x,&y))
union(x,y);
count++;
s.insert(x);
s.insert(y);
}int temp= find(a);//find裡用了路徑壓縮,所以用find陣列找任意一點都可以找到他的最原始的祖先
if(rank[temp]==s.size()&& num==count)
else printf("no\n");
}return 0;
}
hdoj 1272 小希的迷宮
題目 關鍵點 1.特別小心輸入的格式,這個比較糾結。2.題目的最關鍵點 1 所有點的根節點都相同 即下面的count 1 2 輸入路徑不存在回來,這裡用flag來標記回來 即構成迴路,flag 1 3.注意find3 int x 這裡用路徑壓縮的話,速度會快很多 用空間來換時間 ac include...
hdoj1272小希的迷宮
problem description 上次gardon的迷宮城堡小希玩了很久 見problem b 現在她也想設計乙個迷宮讓gardon來走。但是她設計迷宮的思路不一樣,首先她認為所有的通道都應該是雙向連通的,就是說如果有乙個通道連通了房間a和b,那麼既可以通過它從房間a走到房間b,也可以通過它從...
HDOJ 1272 小希的迷宮
題目描述 上次gardon的迷宮城堡小希玩了很久 見problem b 現在她也想設計乙個迷宮讓gardon來走。但是她設計迷宮的思路不一樣,首先她認為所有的通道都應該是雙向連通的,就是說如果有乙個通道連通了房間a和b,那麼既可以通過它從房間a走到房間b,也可以通過它從房間b走到房間a,為了提高難度...