天梯赛--列出连通集代码及注意事项

发布时间 2023-04-22 22:45:14作者: NEETV

问题描述:

给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照"{ v1 v2 ... vk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

输入样例:

8 6

0 7

0 1

2 0

4 1

2 4

3 5

输出样例:

{ 0 1 4 2 7 }

{ 3 5 }

{ 6 }

{ 0 1 2 7 4 }

{ 3 5 }

{ 6 }

设计思路:

标准的bfs与dfs板子题,需要注意的是,存边的时候要注意要按顶点的大小来存,不然输出的时候节点的顺序不是按从小到大排序,会卡测试点。

代码实现:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5;

int n, e;

int cnt = 0;

vector<int> ne[N];

bool st1[N];

void dfs(int x)

{

    st1[x] = true;

    cout << x << ' ';

    for (int i = 0; i < ne[x].size(); i++)

    {

        int t = ne[x][i];

        if (!st1[t])

            dfs(t);

    }

}

void bfs(int x)

{

 

    queue<int> q;

    q.push(x);

    if (cnt)

        cout << endl;

    cnt++;

    cout << "{ ";

    while (q.size())

    {

        int t = q.front();

        q.pop();

        cout << t << ' ';

        for (int i = 0; i < ne[t].size(); i++)

        {

            int u = ne[t][i];

            if (!st1[u])

            {

                st1[u] = true;

                q.push(u);

            }

        }

    }

    cout << '}';

}

int main()

{

    cin >> n >> e;

    for (int i = 0; i < e; i++)

    {

        int a, b;

        cin >> a >> b;

        ne[a].push_back(b);

        ne[b].push_back(a);

    }

    for (int i = 0; i < n; i++)

        sort(ne[i].begin(), ne[i].end());

    for (int i = 0; i < n; i++)

    {

        if (!st1[i])

        {

            st1[i] = true;

            cout << "{ ";

            dfs(i);

            cout << '}';

            cout << endl;

        }

    }

    for (int i = 0; i < N; i++)

        st1[i] = false;

    for (int i = 0; i < n; i++)

    {

        if (!st1[i])

            st1[i] = true, bfs(i);

    }

 

}