並查集總結篇

2021-07-11 18:57:21 字數 3053 閱讀 2177

1、模板題poj1611the suspects

每個組內的人,同乙個組內都是感染者,問與「0」號人有關的有多少人

#include #includeusing namespace std;

const int maxn = 1000100;

struct ds

void merge(int a,int b)

//x下邊的節點不用改,因為查詢的時候會自動更新

int main()

for(j=1;j<=m;++j)

else

merge(a,b);

}if(flag)

printf("scenario #%d:\nsuspicious bugs found!\n\n",i);

else

printf("scenario #%d:\nno suspicious bugs found!\n\n",i);

}return 0;

}

3、帶權並查集經典題:poj1182食物鏈

我說不明白==參考:

4、並查集水題 挨著就算相交,給定某個線段,詢問這一團的有多少個

#include#include#includeusing namespace std;

int pre[1010],sum[1010];

struct point;

struct edge edge[1010];

int e;//邊數

int find(int x)

void merge(int a,int b)

}double xmult(point a,point b,point c)

bool onsegment(point a,point b,point c)

bool cross(point a,point b,point c,point d)

int main()

,,,,

,,,,,,};

int f[300000],n,m;

char c;

int num[100][100];

void init(int n)

int find(int x)

int main()

void addto(int x,int y)

a[y]=a[x];

return ;

}void cal()

}}int main()

memset(vis,0,sizeof(vis));

for(int i=1;i<=100000;i++) a[i]=i;

mark=1;

count=0;

maxn=0;

// point=0;

addto(x,y);

vis[x]=1;

vis[y]=1;

if(maxn

這個題的題意晦澀難懂,總的做法就是每次將兩個集合合併(原來兩個點就在乙個集合內的不算)合併一次,乙個最開始是等於長度的變數--,最後對這個變數^26取模(快速冪)

#include #include#includeusing namespace std;

#define maxn 10000005

#define mod 1000000007

int f[maxn],n,m,l,r,count;

bool vis[maxn];

int find(int x)

void addto(int x,int y)

long long multi(int x)

return ans;

}int main()

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

*/printf("%lld\n",multi(n-count)%mod);

}return 0;

}

8、 第六個題剛剛說完圖論,這就來了==本題意在求出加入多少邊可以構成雙連通分量,而

構造雙連通分量的加邊數=(原圖的葉節點數+1)/2,用並查集縮點,列舉每個橋,[團]++,=1說明是葉子節點

#include #include #include #include #include using namespace std;

const int n=5006;

vectorg[n];

struct bridge

bg[2*n];

int vis[n],low[n],dfn[n],time;

int fa[n],deg[n];

int n,m,cnt;

void init()

}else

low[u] = min(low[u],dfn[v]);

}}int main()

void addto(int x,int y)

a[y]=a[x];

num[x]+=num[y];

return ;

}int main()

for(int i=1;i

題意:給出乙個圖,問幾筆畫才能經過所有邊

連通圖有乙個性質:其需要畫的筆數=度數為奇數的點數除以2,那麼由於給出的圖並沒有說明是否是連通圖,我們需要用並查集來維護連通圖,並且忽略單點的「子圖」 所以說就和第8題一樣了

#include #include#include#includeusing namespace std;

int a[100005],deg[100005],odd[100005];

bool used[100005];

int fnd(int x)

void addto(int x,int y)

a[y]=a[x];

return ;

}int main()

for(int i=0;iv;

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

if(deg[i]&1)

odd[f]++;

}cnt=0;

for(int i=0;i

本來還有兩個題的,離線版的lca和左偏堆,

和並查集的關係不大,就沒寫

並查集 總結

自己學完後總結一下吧,並查集,我的理解就是乙個查詢與合併,用乙個find函式來查詢自己的祖先也就是根節點,在這過程中還可以進行路徑壓縮,就是讓這個點直接變到根節點之下,還有就是合併,找出這兩個點的根節點,如果根節點不相同的話,就將乙個根節點放到另乙個根節點下面。這道題的就是用並查集做,找出總共有幾個...

並查集總結

用自己的理解來寫好了 有些地方可能不對 不定時更新理解 操作主要為三步 一 初始化 void init 二 查詢 這個為路徑壓縮 就是每次查詢時更新 查詢節點 x 上面所有節點直接使他們連向根節點 每次查詢更新 int find int x 另一種路徑壓縮 不過麻煩了些 作為理解 int find ...

並查集總結

注 此博文是在老師上課之後總結的,屬於課堂筆記,大部分摘自老師提供的課件。並查集總結總結兩點就是 並 和 查 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組...