【华为OD统一考试B卷 | 200分】服务器广播、需要广播的服务器数量( C++ Java JavaScript )
题目描述
服务器连接方式包括直接连接、间接连接。A
和B
直接连接,B
和C
直接连接,则A
和C
间接连接。
直接连接和间接连接都可以发送广播。
给出一个N*M
数组,代表N
个服务器,
matrix[i][j] == 1
,则表示i和j
直接连接;不等于1时,代表i和j间接连接。
matrix[i][i] == 1
,即自己和自己直接连接。
matrix[i][j] == matrix[j][i]
计算初始需要给几百台服务器广播,才可以是每台服务器都收到广播。
输入
输入为n行,每行有N
个数字,为0
或1
,由空格分割,构成N*M
的数组,N
的范围为1 <= N <= 40
输出
输出一个数字,为需要广播的服务器数量
用例一
输入
1 | 1 1
2 | 1 1
输出
1 | 1
说明:
3台服务器互不相连,所以需要分别广播这3台服务器
用例二
输入
1 | 1 0 0
2 | 0 1 0
3 | 0 0 1
输出
1 | 3
说明:
3台服务器互不相连,所以需要分别广播这3台服务器
C++实现
#include <iostream>
#include <vector>
using namespace std;
class UF {
private:
int count;
vector<int> id;
vector<int> sz;
public:
UF(int n) {
count = n;
id.resize(n);
sz.resize(n);
for (int i = 0; i < n; i++) {
id[i] = i;
sz[i] = 1;
}
}
int getCount() {
return count;
}
int find(int p) {
if (p == id[p]) {
return p;
} else {
id[p] = find(id[p]);
return id[p];
}
}
bool unionSet(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) {
return false;
}
if (sz[pRoot] > sz[qRoot]) {
swap(pRoot, qRoot);
}
id[pRoot] = qRoot;
sz[qRoot] += sz[pRoot];
count--;
return true;
}
};
int main() {
string line;
getline(cin, line);
vector<int> firstRow;
size_t pos = 0;
while ((pos = line.find(' ')) != string::npos) {
firstRow.push_back(stoi(line.substr(0, pos)));
line.erase(0, pos + 1);
}
firstRow.push_back(stoi(line));
const int n = firstRow.size();
int arr[n][n];
for (int i = 0; i < n; i++) {
arr[0][i] = firstRow[i];
}
for (int i = 1; i < n; i++) {
getline(cin, line);
pos = 0;
for (int j = 0; j < n; j++) {
size_t nextPos = line.find(' ', pos);
if (nextPos == string::npos) {
arr[i][j] = stoi(line.substr(pos));
} else {
arr[i][j] = stoi(line.substr(pos, nextPos - pos));
pos = nextPos + 1;
}
}
}
UF uf(n);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (arr[i][j] == 1) {
uf.unionSet(i, j);
}
}
}
const int count = uf.getCount();
cout << count << endl;
return 0;
}
Java
import java.util.Scanner;
import java.util.Vector;
public class Main {
static class UF {
private int count;
private int[] id;
private int[] sz;
public UF(int n) {
count = n;
id = new int[n];
sz = new int[n];
for (int i = 0; i < n; i++) {
id[i] = i;
sz[i] = 1;
}
}
public int getCount() {
return count;
}
public int find(int p) {
if (p == id[p]) {
return p;
} else {
id[p] = find(id[p]);
return id[p];
}
}
public boolean unionSet(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) {
return false;
}
if (sz[pRoot] > sz[qRoot]) {
int temp = pRoot;
pRoot = qRoot;
qRoot = temp;
}
id[pRoot] = qRoot;
sz[qRoot] += sz[pRoot];
count--;
return true;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
String[] nums = line.split(" ");
Vector<Integer> firstRow = new Vector<>();
for (String num : nums) {
firstRow.add(Integer.parseInt(num));
}
final int n = firstRow.size();
int[][] arr = new int[n][n];
for (int i = 0; i < n; i++) {
arr[0][i] = firstRow.get(i);
}
for (int i = 1; i < n; i++) {
line = sc.nextLine();
nums = line.split(" ");
for (int j = 0; j < n; j++) {
arr[i][j] = Integer.parseInt(nums[j]);
}
}
UF uf = new UF(n);
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (arr[i][j] == 1) {
uf.unionSet(i, j);
}
}
}
final int count = uf.getCount();
System.out.println(count);
}
}
Js
class UF {
constructor(n) {
this.count = n;
this.id = new Array(n).fill().map((_, i) => i);
this.sz = new Array(n).fill(1);
}
getCount() {
return this.count;
}
find(p) {
if (p === this.id[p]) {
return p;
} else {
this.id[p] = this.find(this.id[p]);
return this.id[p];
}
}
unionSet(p, q) {
const pRoot = this.find(p);
const qRoot = this.find(q);
if (pRoot === qRoot) {
return false;
}
if (this.sz[pRoot] > this.sz[qRoot]) {
[pRoot, qRoot] = [qRoot, pRoot];
}
this.id[pRoot] = qRoot;
this.sz[qRoot] += this.sz[pRoot];
this.count -= 1;
return true;
}
}
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let firstRow = [];
let arr = [];
rl.on('line', (line) => {
if (firstRow.length === 0) {
firstRow = line.split(" ").map(Number);
const n = firstRow.length;
arr = Array.from({length: n}, () => new Array(n).fill(0));
for (let i = 0; i < n; i++) {
arr[0][i] = firstRow[i];
}
} else {
const nums = line.split(" ").map(Number);
for (let j = 0; j < nums.length; j++) {
arr[arr.length - 1][j] = nums[j];
}
}
}).on('close', () => {
const n = arr.length;
const uf = new UF(n);
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (arr[i][j] === 1) {
uf.unionSet(i, j);
}
}
}
const count = uf.getCount();
console.log(count);
});
python
class UF:
def __init__(self, n):
self.count = n
self.id = [i for i in range(n)]
self.sz = [1 for i in range(n)]
def getCount(self):
return self.count
def find(self, p):
if p == self.id[p]:
return p
else:
self.id[p] = self.find(self.id[p])
return self.id[p]
def unionSet(self, p, q):
pRoot = self.find(p)
qRoot = self.find(q)
if pRoot == qRoot:
return False
if self.sz[pRoot] > self.sz[qRoot]:
pRoot, qRoot = qRoot, pRoot
self.id[pRoot] = qRoot
self.sz[qRoot] += self.sz[pRoot]
self.count -= 1
return True
if __name__ == '__main__':
line = input()
nums = line.split(" ")
firstRow = [int(num) for num in nums]
n = len(firstRow)
arr = [[0 for i in range(n)] for j in range(n)]
for i in range(n):
arr[0][i] = firstRow[i]
for i in range(1, n):
line = input()
nums = line.split(" ")
for j in range(n):
arr[i][j] = int(nums[j])
uf = UF(n)
for i in range(n):
for j in range(i + 1, n):
if arr[i][j] == 1:
uf.unionSet(i, j)
count = uf.getCount()
print(count)