求解图的连通分量两种方法(深度优先遍历DFS和广度优先遍历BFS)

方法一:广度优先遍历BFS

例题:

【问题描述】
 根据输入的图的邻接矩阵A,判断此图的连通分量的个数。请使用邻接矩阵的存储结构创建图的存储,并采用BFS优先遍历算法实现,否则不得分。
【输入形式】
 第一行为图的结点个数n,之后的n行为邻接矩阵的内容,每行n个数表示。其中A[i][j]=1表示两个结点邻接,而A[i][j]=0表示两个结点无邻接关系。
【输出形式】
 输出此图连通分量的个数。
【样例输入】
 5
 0 1 1 0 0
 1 0 1 0 0
 1 1 0 0 0
 0 0 0 0 1
 0 0 0 1 0
【样例输出】
 2
【样例说明】
 邻接矩阵中对角线上的元素都用0表示。(单个独立结点,即与其它结点都没有边连接,也算一个连通分量)

#include
using namespace std;
#include
#define MAX_VERTEX_NUM 100
#define INFINITY 32768
#define True 1
#define False 0
int visited[100]={False};
typedef struct ArcNode
{
    int adj;
}ArcNode;
typedef struct
{
    int vertex[MAX_VERTEX_NUM];
    ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int vexnum,arcnum;
}AdjMatrix;
typedef struct Node
{
    int data;
    struct Node*next;
}LinkQueueNode;
typedef struct
{
    LinkQueueNode*front;
    LinkQueueNode*rear;
}LinkQueue;
int InitQueue(LinkQueue*Q)
{
    Q->front=(LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if(Q->front!=NULL)
    {
        Q->rear=Q->front;
        Q->front->next=NULL;
        return 1;
    }
    else
        return 0;
}
int EnterQueue(LinkQueue*Q,int x)
{
    LinkQueueNode*NewNode;
    NewNode=(LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if(NewNode!=NULL)
    {
        NewNode->data=x;
        NewNode->next=NULL;
        Q->rear->next=NewNode;
        Q->rear=NewNode;
        return 1;
    }
    else return 0;
}
int DeleteQueue(LinkQueue*Q,int *x)
{
    LinkQueueNode*p;
    if(Q->front==Q->rear)
        return 0;
    p=Q->front->next;
    Q->front->next=p->next;
    if(Q->rear==p)
        Q->rear=Q->front;
    *x=p->data;
    free(p);
    return 1;
}
void CrtAdjMatrix(AdjMatrix*a)
{
    int i,j;
    cin>>a->vexnum;
    for (i = 1; i <= a->vexnum; i++) {
    a->vertex[i] = i;
    }
    for(i=1;i<=a->vexnum;i++)
    {
        for(j=1;j<=a->vexnum;j++)
        {
            a->arcs[i][j].adj=0;
        }
    }
    for(i=1;i<=a->vexnum;i++)
    {
        for(j=1;j<=a->vexnum;j++)
        {
            cin>>a->arcs[i][j].adj;
        }
    }

}
int isEmpty(LinkQueue *Q)
{
    if(Q->front==Q->rear)
        return 1;
    else
        return 0;
}
int FirstAdjVertex(AdjMatrix a,int v)
{
    int j;
    for(j=1;j<=a.vexnum;j++)
    {
        if(a.arcs[v][j].adj!=0)
            return j;
    }
    return -1;
}
int NextAdjVertex(AdjMatrix a,int v,int w)//两种写法都可以
{
    int j;
    for(j=w+1;j<=a.vexnum;j++)
    {
        if(a.arcs[v][j].adj!=0&&j!=w)
            return j;
    }
    return -1;
}
/*int NextAdjVertex(AdjMatrix a,int v,int w)
{
    int j;
    for(j = w + 1; j <= a.vexnum; j++)
    {
        if(a.arcs[v][j].adj != 0)
            return j;
    }
    return -1;
}*/

void BFS(AdjMatrix*a,int v0)
{
    int w,x;
    LinkQueue Q;
    //cout<vertex[v0]<<' ';
    visited[v0]=True;
    InitQueue(&Q);
    EnterQueue(&Q,v0);
    while(!isEmpty(&Q))
    {
        DeleteQueue(&Q,&x);
        w=FirstAdjVertex(*a,x);
        while(w!=-1)
        {
            if(!visited[w])
            {
                //cout<vertex[w]<<' ';
                visited[w]=True;
                EnterQueue(&Q,w);
            }
            w=NextAdjVertex(*a,x,w);
        }
    }
}
int main()
{
    int i,cot=0;
    AdjMatrix *a = (AdjMatrix *)malloc(sizeof(AdjMatrix));
    CrtAdjMatrix(a);
    for(i=1;i<=a->vexnum;i++)
    {
        if(!visited[i])
        {
            BFS(a,i);
            cot++;
        }
    }
    cout<

方法二:深度优先遍历DFS

例题:

【题目描述】

此题必须采用邻接表的存储结构,建立图的存储,然后采用DFS遍历实现求解。否则不给分。

警察抓到了 n 个罪犯,警察根据经验知道他们属于不同的犯罪团伙,却不能判断有多少个团伙,但通过警察的审讯,知道其中的一些罪犯之间相互认识,已知同一犯罪团伙的成员之间直接或间接认识。有可能一个犯罪团伙只有一个人。请你根据已知罪犯之间的关系,确定犯罪团伙的数量。已知罪犯的编号从 1 至 n。

【输入】

第一行:n(<=1000,罪犯数量),第二行:m(<5000,关系数量)以下若干行:每行两个数:I 和 j,中间一个空格隔开,表示罪犯 i 和罪犯 j 相互认识。

【输出】

一个整数,犯罪团伙的数量。

【样例输入】

11

8

1 2

4 3

5 4

1 3

5 6

7 10

5 10

8 9

【输出】

3

#include
using namespace std;
#include
#define MAX_VERTEX_NUM 20
#define TRUE 1
#define FALSE 0
typedef struct ArcNode
{
    int adjvex;
    struct ArcNode*nextarc;
}ArcNode;
typedef struct VertexNode
{
    int data;
    struct ArcNode*firstarc;
}VertexNode;
typedef struct
{
    VertexNode vertex[MAX_VERTEX_NUM];
    int vexnum,arcnum;
}AdjList;
int visited[100]={FALSE};
void DFS(AdjList a,int v0)
{
    //cout<adjvex])
            DFS(a,p->adjvex);
        p=p->nextarc;
    }
}
int main()
{
    int i,j,n,m,x,y,cot=0;
    AdjList* a;
    a=(AdjList*)malloc(sizeof(AdjList));
    cin>>n>>m;
    a->vexnum=n;
    a->arcnum=m;
    for(i=1;i<=n;i++)
    {
        a->vertex[i].firstarc=NULL;
        a->vertex[i].data=0;
    }
    for(i=1;i<=m;i++)
    {
        cin>>x>>y;
        ArcNode*p=(ArcNode*)malloc(sizeof(ArcNode));
        p->nextarc=a->vertex[x].firstarc;
        a->vertex[x].firstarc=p;
        p->adjvex=y;
        ArcNode*q=(ArcNode*)malloc(sizeof(ArcNode));
        q->nextarc=a->vertex[y].firstarc;
        a->vertex[y].firstarc=q;
        q->adjvex=x;
    }
    for(i=1;i<=n;i++)
    {
        if(!visited[i])
        {
            DFS(*a,i);
            cot++;
        }
    }
    cout<

 

你可能感兴趣的:(深度优先,宽度优先,算法)