java并查集计算机网络连通,poj2236 Wireless Network(并查集)
題意:有n臺損壞的電腦,現要將其逐臺修復,且使其相互恢復通信功能。若兩臺電腦能相互通信,則有兩種情況,一是他們之間的距離小于d,二是他們可以借助都可到達的第三臺已修復的電腦。給出所有電腦的坐標位置,對其進行兩種可能的操作,O
x表示修復第x臺,S x y表示判斷x y之間能否通信,若能輸出SUCCESS,否則輸出FALL。
思路:判斷圖的連通性問題,可以借助并查集。首先,電腦之間若能通信,則大前提就是兩臺電腦都是維修過的,因此處理聯通問題時,必須在已修好的電腦中進行。由于通信可以傳遞,因此只要滿足能夠通信的條件,則新加入的電腦就可以借助這個小網絡與其中任意一臺通信,這就是使用并查集的關鍵條件,因此,將滿足距離關系的電腦并入一個集合中,此后每加入一臺電腦都與前面加入的所有電腦做一次聯通性的判斷,即只要距離小于d就并入集合即可。
Accepted 144K 1141MS
#include
#include
#define MAXN 1010
int n, rank[MAXN], father[MAXN], repaired[MAXN];
struct Pos {
int x,
y;
} pos[MAXN];
void make_set()
{
for (int i =
1; i <= n; ++i)
rank[i] = 0, father[i] = i;
}
int find_set(int x)
{
if (x !=
father[x])
father[x] = find_set(father[x]);
return
father[x];
}
void union_set(int x, int y)
{
x =
find_set(father[x]);
y =
find_set(father[y]); // 多向上找一層
if (x !=
y)
{
if (rank[x] < rank[y])
father[x] = y;
else
{
father[y] = x;
if (rank[x] == rank[y])
++rank[x];
}
}
}
double distance(int a, int b) // 注意標號轉換一下
{
Pos x,
y;
x =
pos[a];
y =
pos[b];
return
sqrt(1.0*(x.x-y.x)*(x.x-y.x) + 1.0*(x.y-y.y)*(x.y-y.y));
}
int main()
{
char
c;
int i, x, y,
cnt;
double
d;
scanf("%d%lf", &n, &d);
for (i = 1;
i <= n; ++i) // 編號1到n..
scanf("%d%d", &pos[i].x,
&pos[i].y);
cnt =
0;
make_set();
while
(scanf(" %c%d", &c, &x) !=
EOF)
if (c == 'O')
{
for (i = 0; i
< cnt; ++i) // 與已修好的電腦合并
if
(distance(repaired[i], x) <= d)
union_set(repaired[i],
x);
repaired[cnt++]
= x; // 加入修好的集合中,邏輯其實恰好相反,是先修再合并
}
else
{
scanf("%d", &y);
if
(find_set(x) == find_set(y)) // 判斷連通性
printf("SUCCESS\n");
else
printf("FAIL\n");
}
return
0;
}
總結
以上是生活随笔為你收集整理的java并查集计算机网络连通,poj2236 Wireless Network(并查集)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成电计算机学院保研率,985一条街的街友
- 下一篇: 工行的随心存是什么