开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
今天复习数据结构时刷了一道算法题,关于DFS,我个人认为DFS比BFS要难,所以我们一起看看这道题吧
伽马群岛由若干小岛构成,开发者在某些小岛间修建了水上通路,使得群岛大部分连通,但也不排除部分小岛仍为孤岛,创建伽马群岛的地图,例如:
编写函数数一数该群岛共有多少个小岛。
函数接口定义:
int DFS(AMGraph G, int v);//以v为起点遍历图G(v所在的连通分量)
int DFSTraverse(AMGraph G);//遍历图G
G为图,采用邻接矩阵存储结构,v为起点
这道题使用的是邻接矩阵,其实就是一个接一个的连续的去计数,只需要记录进入dfs的次数就能知道岛屿的数量。当然,有一个值得注意的地方,我们在深搜的时候,需要将搜索到的岛屿置为‘0’,不然就会导致重复搜索。
#include <stdio.h>
#include <stdlib.h>
#define MVNum 100
int visited[MVNum];
typedef struct{
char vexs[MVNum]; //顶点向量
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //顶点数,边数
}AMGraph;
int DFS(AMGraph G, int v);//以v为起点遍历图G(v所在的连通分量)
int DFSTraverse(AMGraph G);//遍历图G
int LocateVex(AMGraph G,char u) //查询顶点u的下标
{
int i,count;
for(i=0;i<G.vexnum;++i)
if( u==G.vexs[i] ) return i;
return -1;
}
void CreateUDG(AMGraph &G){
int i=0,j,count;
char v1,v2;
v1=getchar();
while(v1!='#')
{
G.vexs[i]=v1;
i++;
v1=getchar();
}
G.vexnum=i;
for(i = 0; i< G.vexnum;++i) //初始化邻接矩阵,所有元素均为0
for(j = 0; j< G.vexnum;++j)
G.arcs[i][j] = 0;
scanf("\n%c %c",&v1,&v2);
while(v1!='#'&& v2!='#')
{
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[i][j] = 1;
G.arcs[j][i] = 1;
scanf("\n%c %c",&v1,&v2);
}
}
int main(){
AMGraph G;
CreateUDG(G);
printf("%d",DFSTraverse(G));
return 0;
}
/* 请在这里填写答案 */
输入格式:
第1行依次输入若干顶点的值(顶点之间无间隔),以‘#’结束(顶点不包含#) 接下来若干行输入每条边的信息,格式为:v1空格v2,直到输入‘# #’结束。
输出一个整数,为小岛数量 输入样例:
ABCD# A B A C
输出样例:
4
答案:
#include <iostream>
using namespace std;
int DFS(AMGraph G, int v){
int res = 1;
visited[v]=true;
for(int w=0;w<G.vexnum;w++){
if((G.arcs[v][w]!=0)&&(!visited[w])){
res+=DFS(G,w);
}
}
return res;
}
int DFSTraverse(AMGraph G){
int res=0;
for(int v=0;v<G.vexnum;++v){
visited[v]=false;
}
for(int v=0;v<G.vexnum;++v){
if(!visited[v]){
res+=DFS(G,v);
}
}
return res;
}
另外还有类似的小岛面积、飞地面积题,都是会用到DFS、BFS算法的