对于给定的无向图以及图中的两个顶点,计算两个顶点所在的连通分量中的顶点数,并且判断这两个顶点之间是否有路径。
输入格式:
第一行是不超过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
思路:
用基于重量的并查集,前两问求点v,w所在连通分量的顶点数其实就是求v,w点的最终父节点(eg:find(v))的重量weight[find(v)],千万不要忘记合并时要判断两点的最终父节点是否相同(相同就不用合并了!!!被这个卡了好一会);第三问判断两点之间有无路径就是判断两个点的最终父节点是否一样。
代码:
import java.util.Scanner;
public class Main {
//并查集思路,合并两个点就让这两个点的最终父节点一样
private int[] parent;
private int[] weight;//重量
//初始化
public void unionFind(int size){
parent=new int[size];
weight=new int[size];
for(int i=0;i<size;i++){
parent[i]=i;
weight[i]=1;
}
}
//查找最终父结点
public int find(int element){
while(element!=parent[element]){
element=parent[element];
}
return element;
}
//判断是否连接
public Boolean isConnected(int firstElement,int secondElement){
return find(firstElement)==find(secondElement);
}
//就重量合并
public void unionElement(int firstElement,int secondElement){
int first=find(firstElement);
int second=find(secondElement);
if(first!=second){//一定要判断!!!!
if(weight[first]>weight[second]){//重量大的当父节点
parent[second]=first;
weight[first]+=weight[second];
}
else{
parent[first]=second;
weight[second]+=weight[first];
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in=new Scanner(System.in);
int N,v,w;//顶点数,最后判断的两个顶点
N=in.nextInt();
int a;
Main union=new Main();
union.unionFind(N);//初始化
int[][] tmp=new int[N][N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
tmp[i][j]=in.nextInt();
if(tmp[i][j]==1&&tmp[j][i]!=1&&union.find(i)!=j&&union.find(j)!=i){
union.unionElement(i, j);//合并元素
}
}
}
v=in.nextInt();w=in.nextInt();
System.out.println(union.weight[union.find(v)]);
System.out.println(union.weight[union.find(w)]);
if(N==1){
System.out.println("Yes");
return;
}
if(union.isConnected(v, w)){
System.out.println("Yes");
}
else{
System.out.println("No");
}
}
}