给定一个 n 个节点的邻接矩阵 m。 节点定义为城市,如果 a 城市与 b 城市相连, b 与 c 城市相连,尽管 a 与 c 并不直接相连,但可以认为 a 与 c 相连,定义 a,b,c 是一个城市群。
矩阵 m[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,否则表示不相连。
请你找出共有多少个城市群。
数据范围:
, 矩阵中只包含
和
[[1,1,0],[1,1,0],[0,0,1]]
2
1 2 相连,3 独立,因此是 3 个城市群。
[[1,1,0,0],[1,1,1,0],[0,1,1,0],[0,0,0,1]]
2
1 , 2相连 ;2 ,3相连,4独立,因此是 1,2,3 属于一个城市群,4属于一个城市群。
import java.util.*;
/**
* NC345 城市群数量
* @author d3y1
*/
public class Solution {
private int result = 0;
private int N;
private boolean[] isVisited;
private HashSet<Integer>[] adj;
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型ArrayList<ArrayList<>>
* @return int整型
*/
public int citys (ArrayList<ArrayList<Integer>> m) {
// return solution1(m);
// return solution2(m);
return solution3(m);
}
/**
* dfs
* @param m
* @return
*/
private int solution1(ArrayList<ArrayList<Integer>> m){
N = m.size();
isVisited = new boolean[N];
adj = new HashSet[N];
for(int i = 0; i < N; i++){
adj[i] = new HashSet<>();
}
for(int i = 0; i < N; i++){
for(int j = i+1; j < N; j++){
if(m.get(i).get(j) == 1){
adj[i].add(j);
adj[j].add(i);
}
}
}
for(int i = 0; i < N; i++){
if(!isVisited[i]){
dfs(i);
result++;
}
}
return result;
}
/**
* 递归
* @param city
*/
private void dfs(int city){
if(isVisited[city]){
return;
}
isVisited[city] = true;
for(int adjCity: adj[city]){
dfs(adjCity);
}
}
/**
* bfs
* @param m
* @return
*/
private int solution2(ArrayList<ArrayList<Integer>> m){
N = m.size();
isVisited = new boolean[N];
adj = new HashSet[N];
for(int i = 0; i < N; i++){
adj[i] = new HashSet<>();
}
for(int i = 0; i < N; i++){
for(int j = i+1; j < N; j++){
if(m.get(i).get(j) == 1){
adj[i].add(j);
adj[j].add(i);
}
}
}
for(int i = 0; i < N; i++){
if(!isVisited[i]){
bfs(i);
result++;
}
}
return result;
}
/**
* 非递归: 队列
* @param city
*/
private void bfs(int city){
Queue<Integer> queue = new LinkedList<>();
queue.offer(city);
int currCity;
while(!queue.isEmpty()){
currCity = queue.poll();
isVisited[currCity] = true;
for(int adjCity: adj[currCity]){
if(!isVisited[adjCity]){
queue.offer(adjCity);
}
}
}
}
/**
* 并查集
* @param m
* @return
*/
private int solution3(ArrayList<ArrayList<Integer>> m){
int n = m.size();
UnionFind uf = new UnionFind(n);
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
if(m.get(i).get(j) == 1){
uf.union(i,j);
}
}
}
return uf.connects();
}
/**
* 并查集类
*/
private class UnionFind {
int connect;
int[] parent;
UnionFind(int n){
this.connect = n;
parent = new int[n];
for(int i=0; i<n; i++){
parent[i] = i;
}
}
int find(int x){
while(x != parent[x]){
// parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
void union(int p, int q){
int rootP = find(p);
int rootQ = find(q);
if(rootP != rootQ){
parent[rootP] = rootQ;
this.connect--;
}
}
int connects(){
return this.connect;
}
}
} 并查集常规题,熟练一遍模板
class Solution:
def citys(self , m: List[List[int]]) -> int:
n = len(m)
arr = [0] * n
for i in range(n):
arr[i] = i
def find(i):
if arr[i] == i:
return i
arr[i] = find(arr[i])
return arr[i]
def union(i, j):
arr[find(i)] = find(j)
for i in range(1, n):
for j in range(i):
if m[i][j] == 1:
union(i, j)
ret = 0
for i in range(n):
if i == arr[i]:
ret += 1
return ret public class Solution {
int[] arr;
public int citys (ArrayList<ArrayList<Integer>> m) {
// write code here
int n = m.size();
arr = new int[n];
for (int i = 0; i < n; ++i)
arr[i] = i;
for (int i = 1; i < n; ++i)
for (int j = 0; j < i; ++j)
if (m.get(i).get(j) == 1)
union(i, j);
int ret = 0;
for (int i = 0; i < n; ++i)
if (arr[i] == i)
ret++;
return ret;
}
private int find(int i) {
if (i == arr[i])
return i;
arr[i] = find(arr[i]);
return arr[i];
}
private void union(int i, int j) {
arr[find(i)] = find(j);
}
}
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型vector<vector<>>
* @return int整型
*/
vector<int>f;
int find(int x){
if(this->f[x]==x)return x;
else return this->f[x]=find(this->f[x]);
}
void merge(int a,int b){
int x=find(a);
int y =find(b);
this->f[x]=y;
}
int citys(vector<vector<int> >& m) {
// write code here
// 初始化
this->f=vector<int>(m.size());
int n=m.size();
for(int i=0;i<n;i++){
this->f[i]=i;
}
// 合并相连城市
for(int i=0;i<n;i++){
for(int j=0;j<m[i].size();j++){
if(m[i][j]==1){
merge(i,j);
}
}
}
//通过unordered_set统计城市群数量
int cntFather=0;
unordered_set<int >st;
for(int i=0;i<n;i++){
st.insert(find(i));
}
cntFather=st.size();
return cntFather;
}
}; /**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型二维数组
* @param mRowLen int m数组行数
* @param mColLen int* m数组列数
* @return int整型
*/
void dfs(int** m, int mr, int mc,int i){
for(int j=0;j<mr;j++){
if(m[i][j]==1){
m[i][j]=0;
m[j][i]=0;
dfs(m,mr,mc,j);
}
}
}
int citys(int** m, int mRowLen, int* mColLen ) {
// write code here
int count=0;
for(int i=0;i<mRowLen;i++){
for(int j=0;j<*mColLen;j++){
if(m[i][j]==1){
count++;
m[i][j]=0;
m[j][i]=0;
dfs(m,mRowLen,*mColLen,i);
dfs(m,mRowLen,*mColLen,j);
}
}
}
return count;
} class Solution: map=[] def citys(self , m: List[List[int]]) -> int: num=0 self.map=[0]*len(m) for i in range(len(m)): if self.map[i]==0: num+=1 self.dfs(i,m) return num def dfs(self,x,m): self.map[x]=1 for i in range(len(m[x])): if m[x][i]==1 and self.map[i]==0: self.dfs(i,m)
# python3 # 并查集做法 # 总城市肯定是m # 每有两个城市互相连接,数量就减1 class Solution: def __init__(self): self.n = 210 self.father = [i for i in range(self.n)] def find(self, u): if u == self.father[u]: return u self.father[u] = self.find(self.father[u]) return self.father[u] def same(self, u, v): u = self.find(u) v = self.find(v) if u == v: return True return False def join(self, u, v): u = self.find(u) v = self.find(v) if u == v: return self.father[u] = v pass def citys(self , m: List[List[int]]) -> int: # write code here cnt = len(m) for i in range(len(m)): for j in range(len(m[0])): if m[i][j] == 1: if not self.same(i, j): self.join(i, j) cnt -= 1 else: continue return cnt
class UF {
public:
UF() = default;
UF(int n) {
cnt = n;
parent.resize(n);
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
int find(int x) {
while (x != parent[x]) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
void ufUnion(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot) return;
parent[pRoot] = qRoot;
cnt--;
}
bool isConnected(int p, int q) {
return find(p) == find(q);
}
int count() {
return cnt;
}
private:
int cnt;
vector<int> parent;
};
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型vector<vector<>>
* @return int整型
*/
int citys(vector<vector<int> >& m) {
// write code here
int n = m.size();
UF uf(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (m[i][j] == 1)
uf.ufUnion(i, j);
}
}
return uf.count();
}
}; public class Solution {
// dfs遍历邻接矩阵就可以
public int citys (ArrayList<ArrayList<Integer>> matrix) {
int m = matrix.size();
v = new boolean[m];
int cnt = 0;
for (int i = 0; i < m; i++) {
if (!v[i]) {
cnt++;
dfs(i, matrix, m);
}
}
return cnt;
}
boolean[] v;
public void dfs(int i, ArrayList<ArrayList<Integer>> matrix, int m) {
if (!v[i]) {
v[i] = true;
for (int j = 0; j < m; j++) {
if (matrix.get(i).get(j) == 1) {
dfs(j, matrix, m);
}
}
}
}
}
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型ArrayList<ArrayList<>>
* @return int整型
*/
public int citys (ArrayList<ArrayList<Integer>> m) {
// write code here
int n = m.size();
int k = m.get(0).size();
// int[][] arr = new int[n][k];
int[] visited = new int[n];
int ans = 0;
for(int i = 0;i<n;i++){
// System.out.println(i);
if(visited[i] == 0){
ans++;
dfs(m,visited,i);
}
}
return ans;
}
public void dfs(ArrayList<ArrayList<Integer>> m,int[] visited,int node){
visited[node] = 1;
ArrayList<Integer> arr = m.get(node);
for(int i = 0;i<arr.size();i++){
if(arr.get(i)!=0 && visited[i] == 0){
dfs(m,visited,i);
}
}
}
}