對於給定的無向圖以及圖中的兩個頂點,計算兩個頂點所在的連通分量中的頂點數,並且判斷這兩個頂點之間是否有路徑。
輸入格式:
第一行是不超過20
的正整數N
,表示圖有N
個頂點,頂點的編號即0
~N-1
;
接下來N
行,是N*N
的鄰接矩陣,矩陣的元素間用空格分隔;
最後一行是用空格隔開的兩個頂點編號v
和w
輸出格式:
第一行輸出v
所在的連通分量的頂點數
第二行輸出w
所在的連通分量的頂點數
第三行,若v
和w
之間有路徑,則輸出Yes
,否則輸出No
注意:當v
和w
是同一個頂點時,認爲v
和w
之間是有路徑的。
輸入樣例:
對於這個圖:
8
0 1 1 0 0 0 0 1
1 0 0 0 1 0 0 0
1 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 3
輸出樣例:
5
2
No
代碼如下:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] node = new int[n];
int[] weight = new int[n];
for(int i=0;i<n;i++) {
node[i] = i;
weight[i] = 1;
}
int[][] map = new int[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) {
map[i][j] = sc.nextInt();
if(map[i][j]==1) {
int rooti = find(i, node);
int rootj = find(j, node);
if(rooti!=rootj) {
node[rootj] = rooti;
weight[rooti] += weight[rootj];
}
}
}
int x = sc.nextInt(), y = sc.nextInt();
int rooti = find(x, node);
int rootj = find(y, node);
System.out.println(weight[rooti]);
System.out.println(weight[rootj]);
if(rooti==rootj) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
public static int find(int i, int[] node) {
while(node[i]!=i)
i = node[node[i]];
return i;
}
}
這個題實際上感覺挺簡單的,我用到的方法是並查集,因爲需要統計每個連通部分的節點數,所以更進一步來說是基於重量的連接的並查集算法,因爲沒有運行超時所以沒再過多的優化,這個題是我最近感覺做的最順暢的一個題了。