邻接表运用

一.邻接表的使用方法

   使用一个支持动态增加元素的数据结构构成的数组,如 vector<int> adj[n + 1] 来存边,其中 adj[u] 存储的是点  的所有出边的相关信息(终点、边权等)。

二.例题

1.树的遍历

题目描述

给定一棵大小为n,根为1的树,求出其dfs序、bfs序。

请将所有出点按照编号从小到大排序后进行遍历。

解释:dfs为深度优先搜索,bfs为宽度优先搜索。

输入格式

一个整数n,表示点的个数。(1≤n≤50)

接下来一行n−1个整数,第i个数字fai​表示点i的父亲。(1≤fai​≤n)

输出格式

第一行输出dfs序,第二行输出bfs序。

样例输入1

4
1 1 2

样例输出1

1 2 4 3
1 2 3 4

代码示例

#include <bits/stdc++.h>
using namespace std;

const int N = 60;
int root[N], n;

vector<int> g[N];

void dfs(int x) {
    cout << x << ' ';
    for(auto &y : g[x]) dfs(y);
    /*for(int j = 0; j < g[x].size(); j++) {
        int y = g[x][j];
        dfs(y);// 进行操作,比如输出或者其他处理
    }*/
}


void bfs(int rt) {
    queue<int> q;
    q.push(rt);
    while(q.size()) {
        int x = q.front(); q.pop();
        cout << x << ' ';
        for(auto &y : g[x]) q.push(y);
    }
}

int main() {
    cin >> n;
    for(int i = 2; i <= n; i++) cin >> root[i];
    for(int i = 2; i <= n; i++) g[root[i]].push_back(i);
    for(int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end());
    
    dfs(1);
    cout << '\n';
    bfs(1);
    
    return 0;
}

2.图的遍历

题目描述

给定一个n个点m条边的有向图,图中可能存在重边和自环,点的编号为1~n。

你需要求出从点1出发,能够到达的所有点。

输入描述

第一行:两个整数n,m,分别表示有向图的点数、边数。(1≤n,m≤10^{5}

接下来m行:每行两个整数ui​,vi​,表示存在一条从ui​到vi​的有向边。(1≤ui​,vi​≤n)

输出描述

共一行,从小到大输出1号点能够到达的点的编号。

输入样例1

5 3
1 2
2 4
4 5

输出样例1

1 2 4 5

题目分析

         由于本题可能存在自环,故而需要特判;(无权值的重边忽略即可,不影响做题);然后从1号点开始深搜即可。


代码示例

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

vector<int> g[N];
bitset<N> st; //状态数组


void dfs(int x) {
    if(st[x]) return ;
    st[x] = 1;
    for(auto &y : g[x]) dfs(y);
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m; cin >> n >> m;
    
    int u, v;
    for(int i = 1; i <= m; i++) {
        cin >> u >> v;
        if(u != v)g[u].push_back(v);//判断是否为自环,若为自环,不入数组
    }
    
    dfs(1);
    
    for(int i = 1; i <= n; i++) if(st[i]) cout << i << ' ';//dfs遍历顺序即为由小到大的顺序
    return 0;
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值