题目:
对于给定的无向图以及图中的两个顶点,计算两个顶点所在的连通分量中的顶点数,并且判断这两个顶点之间是否有路径。
输入格式:
第一行是不超过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
思路:
这道题发现可以用并查集来进行求解,不过这里唯一需要注意的是counts这个计数的数组,在join函数中一定要用max函数求出这两个counts中的最大值,要不然无法将其合并。
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
const int maxn = 30;
int pre[maxn];
int counts[maxn];
int matrix[maxn][maxn];
int find(int x)
{
return pre[x] == x ? x : (pre[x] = find(pre[x]));
}
void join(int x, int y)
{
int find1 = find(x);
int find2 = find(y);
if (find1 != find2)
{
pre[find1] = find2;
//counts[find2]++;
counts[find2] = max(counts[find1], counts[find2]) + 1;
}
}
int main()
{
for (int i = 0; i < maxn; ++i)
pre[i] = i;
fill(counts,counts+maxn,1);
cin >> n;
int t;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cin >> t;
matrix[i][j] = t;
if (t == 1 && matrix[j][i] == 0)
join(i, j);
}
}
int n1, n2;
cin >> n1 >> n2;
int findn1 = find(n1);
int findn2 = find(n2);
cout << counts[findn1] << endl << counts[findn2] << endl;
if (findn1 == findn2)
cout << "Yes";
else
cout << "No";
return 0;
}