曾经沧海难为水,除却巫山不是云。|

Joey-Wang

园龄:4年3个月粉丝:17关注:0

10.3 图的遍历

10.3 图的遍历

http://codeup.hustoj.com/contest.php?cid=100000620

B 连通图

image-20200828205154636

题目解析

倾向于用邻接表做所有的图题目,因为邻接图要求顶点数目不超过1000,否则内存超限

这道题就是遍历整个图,一次DFS/BFS能完成一个连通子图的遍历,BFS/DFS的次数就是图含有连通子图的个数

⚠️注意DFS/BFS代码的写法
DFS中用vis数组表示结点是否已访问;BFS中用inq数组表示结点是否入过队,且在push结点temp时要设置inq[temp]=true,而DFS中在往下遍历DFS(v)时不用设置vis[v]=true,因为每次DFS开头都会设置vis[u] = true

PS:我觉得这道题也可以用并查集做

代码(DFS)

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 10001
using namespace std;
int n, m;
vector<int> Adj[maxn];
bool vis[maxn] = {false};

void DFS(int u) {
    vis[u] = true;
    for (int i = 0; i < Adj[u].size(); i++) {
        int v = Adj[u][i];
        if (!vis[v]) {
            DFS(v);
        }
    }
}

void DFSTrave() {
    int time=0;
    for (int u = 1; u <= n; u++) {
        if (!vis[u]) {
            DFS(u);
            time++;
        }
    }
    if (time==1) printf("YES\n");
    else printf("NO\n");
}

int main() {
    int a,b;
    while (scanf("%d%d", &n, &m) && n) {
        for(int i=1;i<=n;i++) Adj[i].clear();
        memset(vis,0,sizeof(vis));
        while(m--){
            scanf("%d%d",&a,&b);
            Adj[a].push_back(b);
            Adj[b].push_back(a);
        }
        DFSTrave();
    }
    return 0;
}

代码(BFS)

#include <queue>
#include <vector>
#include <cstring>
#define maxn 10001
using namespace std;
vector<int> Adj[maxn];
bool inq[maxn] = {false};
int n, m;

void BFS(int u) {
    queue<int> q;
    q.push(u);
    inq[u] = true;
    while (!q.empty()) {
        int v = q.front();
        q.pop();
        for (int i = 0; i < Adj[v].size(); i++) {
            int temp = Adj[v][i];
            if (!inq[temp]) {
                inq[temp] = true;
                q.push(temp);  // 注意!!!!
            }
        }
    }
}

void BFSTrave() {
    int time = 0;
    for (int i = 1; i <= n; i++) {
        if (!inq[i]) {
            BFS(i);
            time++;
        }
    }
    if (time == 1) printf("YES\n");
    else printf("NO\n");
}

int main() {
    int a, b;
    while (scanf("%d%d", &n, &m) && n) {
        for (int i = 1; i <= n; i++) Adj[i].clear();
        memset(inq, 0, sizeof(inq));
        while (m--) {
            scanf("%d%d", &a, &b);
            Adj[a].push_back(b);
            Adj[b].push_back(a);
        }
        BFSTrave();
    }
    return 0;
}

本文作者:Joey-Wang

本文链接:https://www.cnblogs.com/joey-wang/p/14541190.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(64)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开