主要是為了複習內容,好讓自己安心一點
之前學習並查集的時候,並沒有系統地學習圖論的知識,現在再看過來,又要好一些了。
根據目前的理解,並查集就是:
無向圖中有關聯的部分連通
判斷一條邊是否成環
前提全域性變數:
int fa[n]
;//祖宗
int rank[n]
;//成員數
void
init()
find函式:
找爸爸
int
find1
(int x)
網上還看到一種迴圈的寫法,挺好的
int
find2
(int x)
路徑壓縮
我直接認祖宗
int
zip(
int x)
union
兩個家族聯姻了
void
union
(int x1,
int x2)
else
}
在連通網的所有生成樹中,所有邊的代價和最小的生成樹,稱為最小生成樹。
在最小生成樹問題中,一般有兩種演算法
kruskal
prim
kruskal演算法
適合簡單圖
總體思路就是,邊權排序一次(使用了sort),從小到大遍歷邊,如果邊的兩點未連線,就連起來,直到連線n-1個邊,那麼整個圖就連通了,並且邊權最小。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma warning(disable:4996)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f
#define itn int
#define ll long long
#define mes(a,k) memset(a,k,sizeof(a))
//#define max(a,b) a>b?a:b
//#define min(a,b) a#define pb(a) push_back(a)
#define eps 1e-9
#define pi acos(-1)
using
namespace std;
const
int n =
2e5+5;
using
namespace std;
int n,m,cnt=
0,res=0;
//例項用到的
int fa[n]
;//祖宗
int rank[n]
;//成員數
int t;
//儲存邊
struct nodeedge[n]
;voidio(
)bool
cmp(
const node &a,
const node &b)
//初始化
void
init()
//找爸爸遞迴版
intfind1
(int x)
//找爸爸迴圈版
intfind2
(int x)
//路徑壓縮
intzip
(int x)
//聯合
void
union
(int x1,
int x2)
else
}int
main()
} cout
}
並查集學習總結
並查集,在一些有n個元素的集合應用問題中,我們通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪個集合中。這一類問題近幾年來反覆出現在資訊學的國際國內賽題中,其特點是看似並不複雜,但資料量極大,若用正常的資料結構來描述的話,往往在...
並查集 總結
自己學完後總結一下吧,並查集,我的理解就是乙個查詢與合併,用乙個find函式來查詢自己的祖先也就是根節點,在這過程中還可以進行路徑壓縮,就是讓這個點直接變到根節點之下,還有就是合併,找出這兩個點的根節點,如果根節點不相同的話,就將乙個根節點放到另乙個根節點下面。這道題的就是用並查集做,找出總共有幾個...
並查集總結
用自己的理解來寫好了 有些地方可能不對 不定時更新理解 操作主要為三步 一 初始化 void init 二 查詢 這個為路徑壓縮 就是每次查詢時更新 查詢節點 x 上面所有節點直接使他們連向根節點 每次查詢更新 int find int x 另一種路徑壓縮 不過麻煩了些 作為理解 int find ...