图的遍历(邻接表 | 链式前向星)
题目链接
先上题目(多多关注_qaq )
题目描述
给出 个点, 条边的有向图,对于每个点 ,求 表示从点 出发,能到达的编号最大 的点。
输入格式
第 行, 个整数 。
接下来 行,每行2个整数 ,表示边 。点用 编号。
输出格式
个整数 。
输入
4 3
1 2
2 4
4 3
输出
4 4 3 4
说明/提示
• 对于 % 的数据, • 对于 % 的数据,
本人暴力枚举的时候,自己编译时,发现只有样例过了,自己编的数据一个都没
过(内心有点酸~~~),后来才发现其实是邻接表。
邻接矩阵
先引入一下邻接矩阵吧。!!!不是邻接表
对于一张图~~
我们可以先弄一张表格,如下:
|0| 1 |1 | |--|--|--|--|--| | 1 | 0 |0|||| |1|0|0||
其中,第i行第j列 表示 第i个城市和第j个城市是否联通(1为是,0为否)
由此,我们可得知 邻接矩阵具有对称性
众所周知 邻接矩阵空间和时间复杂度都是
让我们想一个问题:如果n为 呢?,那么将会有大量的空间被浪费。
邻接表
由此,神诞生了——邻接表~~~(此处省略巨多音效 )
尊称:链式前向星
简介:空间和时间复杂度就都是 。对于稀疏图来说, 要远远小于 。
假设有 个点, 条边
3 3 1 2 1 3 2 3
序号 | head | to | next |
---|---|---|---|
① | 2 | 2 | 0 |
② | 3 | 3 | 1 |
③ | 0 | 3 | 0 |
可以发现,从第 点开始遍历,就先找到 的序号,再找到
(为点 可以到达的边的序号,接下来, 就变成 ,接着循坏
————(本人第一次做 了无数次_QAQ)
举 为栗子:先找到 ,值为 ,接着找到 ,值为 ,记录 可以到达 ,再找到 ,值为 ,然后找到 ,值为 ,记录 可以到达 ,最后找到 ,值为 ,结束遍历。
可以到达
也可以用结构体存储 和 数组
void add(int a, int b)
{ //插入
p++;
t[p].next = head[a];
head[a] = p;
t[p].to = b;
}
上机程序片段
for(int i = head[x]; i; i = t[i].next)
请查阅 https://blog.csdn.net/vocaloid01/article/details/76576822
https://so.csdn.net/so/search/all?q=%E9%82%BB%E6%8E%A5%E8%A1%A8&t=all&p=1&s=0&tm=0&lv=-1&ft=0&l=&u=
(才是真正的神! ! ! )
相对于链式前向星, 则更为简单。
定义
const int maxn = 1e5 + 99;
struct Edge
{
int to, w;
};
vector<Edge> d[maxn];
初始化
for (int i = 0; i < maxn; i++)
d[i].clear();
建图
//在点A和点B之间建立一条权值为K的有向边
d[A].push_back({B, k});
遍历
for (int i = 0; i < d[tmp].size(); i++)
主要思路
对于一个点j,只需要把与j链接的点 感染 注意是逆序,就不用判断了——QAQ 如果有强迫症的话,就用
接下来就是 插入要反过来 便于感染
add(b,a);
然后从大的点i开始遍历,找到一个点 开始感染(附值)——而如果有一个比点 小的点 ,也找到了点 ,那就直接跳过(因为 )节约时间
if (mmax[x])
return;
mmax[x] = u;
#include <bits/stdc++.h>
using namespace std;
int n, m, a, b, x, y, c[100001], head[100001], mmax[100001], p;
struct abc
{
int to, next;
} t[100001];
void dfs(int x, int u)
{ //深搜
if (mmax[x])
return;
mmax[x] = u; //感染 mmax[x]=max(mmax[x],u);
for (int i = head[x]; i; i = t[i].next)
{
dfs(t[i].to, u);
}
}
void add(int a, int b)
{ //插入
p++;
t[p].next = head[a];
head[a] = p;
t[p].to = b;
}
int main()
{
cin >> m >> n;
for (int i = 1; i <= n; i++)
{
cin >> a >> b;
add(b, a);
}
for (int u = m; u >= 1; u--)
{ //重点:注意是逆向 后面就不用max()了————啊哈哈~
dfs(u, u); //第二个u是用来感染的“病毒”
}
for (int i = 1; i <= m; i++)
cout << mmax[i] << " ";
//cout<<endl<<endl;
//for(int i=1;i<=m;i++)printf("%3d. %3d %3d %3d\n",i,head[i],t[i].to,t[i].next);
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122238
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话