题意
给定一个邻接矩阵 求有几个连通块
这是图论非常入门的题了吧 不过我才刚会做哈哈哈
其实非常简单 接下来要开始系统地学图论和dp了
方法一 DFS/BFS
思路
就是遍历每个点 如果没有被标记过 就cnt++
并且对他搜索 把所有跟他联通的点都标记上
Code
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);};
void cmin(int &a,int b){a=min(a,b);};
const int N=210,MOD=1e9+7,INF=0x3f3f3f3f;const long long LINF=LLONG_MAX;const double eps=1e-6;
bool vis[N];
vector<vector<int>>g;
int n;
class Solution {
public:
int findCircleNum(vector<vector<int>>& grid) {
g=grid;
n=g.size();
int cnt=0;
memset(vis,0,sizeof vis);
for(int i=0;i<n;i++){
if(!vis[i]){
vis[i]=1;
cnt++;
bfs(i);//dfs(i)也一样
}
}
return cnt;
}
void bfs(int u){
queue<int>q;
q.emplace(u);
while(q.size()){
int v=q.front();q.pop();
for(int i=0;i<n;i++){
if(vis[i]==0&&g[v][i]){
vis[i]=1;
q.emplace(i);
}
}
}
}
void dfs(int u){
for(int v=0;v<n;v++){
if(g[u][v]&&vis[v]==0){
vis[v]=1;
dfs(v);
}
}
}
};
方法二 并查集求连通块数量
思路
这个题意很显然可以并查集做
如何维护连通块数量呢?
其实很简单 不过我做这题时才知道
就是把cnt初始化成元素个数
每次合并时cnt–就行了
Code
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);};
void cmin(int &a,int b){a=min(a,b);};
const int N=210,MOD=1e9+7,INF=0x3f3f3f3f;const long long LINF=LLONG_MAX;const double eps=1e-6;
int p[N];
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
class Solution {
public:
int findCircleNum(vector<vector<int>>& g) {
int n=g.size();
int cnt=n;
for(int i=0;i<n;i++){
p[i]=i;
}
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
if(!g[i][j]) continue;
int ii=find(i),jj=find(j);
if(ii!=jj){
p[ii]=jj;
cnt--;
}
}
}
return cnt;
}
};