並查集的使用
並查集實際上是資料結構中樹的應用,每個子樹最終連線到一個根節點上
演算法實現,包括find()函式--找到子樹的根節點,和join()函式--合併子樹
find()演算法實現:
int find(int x)
{
int r=x;
while(r!=pre[r])
{
r = pre[r];
}
int i = x,j = r;
while(i != r) //路徑壓縮演算法
{
j = pre[i];//改變前導節點前記錄值
pre[i] = r;//前導節點改為根節點
i = j;
}
return r;
}
join()演算法實現:
void join(int x,int y) { int fx = find(x); int fy = find(y); if(fx!=fy) { pre[fx] = fy; } }
題目引入:
第八屆藍橋杯:風險度量
X星系的的防衛體系包含 n 個空間站。這 n 個空間站間有 m 條通訊鏈路,構成通訊網。
兩個空間站間可能直接通訊,也可能通過其它空間站中轉。
對於兩個站點x和y (x != y), 如果能找到一個站點z,使得:
當z被破壞後,x和y無法通訊,則稱z為關於x,y的關鍵站點。
顯然,對於給定的兩個站點,關於它們的關鍵點的個數越多,通訊風險越大。
你的任務是:已知網路結構,求兩站點之間的通訊風險度,即:它們之間的關鍵點的個數。
輸入資料第一行包含2個整數n(2 <= n <= 1000), m(0 <= m <= 2000),分別代表站點數,鏈路數。
空間站的編號從1到n。通訊鏈路用其兩端的站點編號表示。
接下來m行,每行兩個整數 u,v (1 <= u, v <= n; u != v)代表一條鏈路。
最後1行,兩個數u,v,代表被詢問通訊風險度的兩個站點。
輸出:一個整數,如果詢問的兩點不連通則輸出-1.
例如:
使用者輸入:
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
應該輸出:
2
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int pre[1005],route[1005][2];
int sum = 0;
int find(int x)
{
int r=x;
while(r!=pre[r])
{
r = pre[r];
}
int i = x,j = r;
while(i != r) //路徑壓縮演算法
{
j = pre[i];//改變前導節點前儲存值
pre[i] = r;
i = j;//改變前導節點的值
}
return r;
}
void join(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx!=fy)
{
pre[fx] = fy;
}
}
int main() {
int n,m;
scanf("%d %d",&n,&m);
for(int i = 0; i<m; i++)
{
scanf("%d %d",&route[i][0],&route[i][1]);
}
int p1,p2;
scanf("%d %d",&p1,&p2);
for(int i = 0; i<n; i++) pre[i] = i;
for(int i = 0; i<m; i++)
{
join(route[i][0],route[i][1]);
}
int a = find(p1);
int b = find(p2);
if(a!=b)
{
printf("-1\n");
}
else
{
for(int i = 1; i<=n; i++)
{
if(p1 == i||p2 == i)
{
continue;
}
for (int j = 1; j <= n; j++)pre[j] = j;
for(int j = 0; j < m; j++)
{
if(route[j][0] == i||route[j][1] == i)
{
continue;
}
int a = find(route[j][0]);
int b = find(route[j][1]);
if(a>b) {
a^=b;
b^=a;
a^=b;
}
if(a!=b)
{
pre[b] = a;
}
}
a = find(p1);
b = find(p2);
if(a!=b) sum++;
}
printf("%d\n",sum);
}
return 0;
}
1、判定是否兩個通訊節點是否聯通
2、連通的前提下遍歷所有節點,去掉該節點與u、v連線的邊,如果u、v依然連通,說明該節點不是關鍵點,否則是關鍵點sum++
相關文章
- 【並查集】【帶偏移的並查集】食物鏈並查集
- 並查集到帶權並查集並查集
- 並查集(一)並查集的幾種實現並查集
- 查並集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- 3.1並查集並查集
- 並查集(小白)並查集
- [leetcode] 並查集(Ⅱ)LeetCode並查集
- [leetcode] 並查集(Ⅲ)LeetCode並查集
- [leetcode] 並查集(Ⅰ)LeetCode並查集
- 使用並查集處理集合的合併和查詢問題並查集
- 並查集的應用2並查集
- 淺談並查集並查集
- 食物鏈(並查集)並查集
- 並查集跳躍並查集
- 各種並查集並查集
- 寫模板, 並查集。並查集
- 並查集(Union Find)並查集
- The Door Problem 並查集並查集
- 並查集練習並查集
- 並查集應用並查集
- 簡單易懂的並查集演算法以及並查集實戰演練並查集演算法
- Soso 的並查集寫掛了並查集
- 並查集的簡單應用並查集
- 並查集擴充套件並查集套件
- (Day3)並查集並查集
- 並查集java實現並查集Java
- 【轉】種類並查集並查集
- The Suspects-並查集(4)並查集
- 並查集-Java實現並查集Java
- 並查集演算法並查集演算法
- 並查集題目合集並查集
- 並查集深度應用並查集
- [複習] 種類並查集並查集
- 資料結構-並查集資料結構並查集
- 並查集の進階用法並查集
- 並查集(UnionFind)技巧總結並查集
- 關於並查集問題並查集