依旧是开头的碎碎念
今天是正式的回学校学习的日子啦,去了if楼写代码,唔比家里要舒服的多(主要是喜欢这个屏幕);花了好几天的时间收拾家呜呜呜累洗掉了啦,今晚还有个cf...大概会掉分叭哭哭,感觉一朝回到解放前,昨晚思考了一下今天学些什么,发现基本上都不会啦(喜报:都不会啦)那还能怎么办呢,只好重新学习惹,不过万幸的是还会写hello world
在准备开图的遍历的时候发现自己在2021年的时候交过那个题不过一发CE没有继续往下写了,突然有些感触,顺便问了问自己当初是怎么写不出题目来还睡得着觉的
今日计划
- 图的概念与建立、遍历
- 数学进位制之间的转换
- CF
- 如果有时间的话继续看图论的知识:最短路,最小生成树
- 复习一下前缀和、拆分
- 背单词
图的存储
图的存储主要有以下几种方式
- 直接存储:建立一个二维数组
- 邻接矩阵:建立一个二维的可变数组,记录边的情况
- 邻接表:一个二维可变数组,记录每个点的所有出边情况
- 链式前向星:本质是用链表实现的邻接表
第四个还没理解清楚qwq
写的洛谷题单里的题目:https://www.luogu.com.cn/problem/B3643
代码如下:
点击查看代码
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
int main(){
int n,m,a,b;
vector< vector<int> >adj;
cin>>n>>m;
vector<int>temp(n+1);
adj.resize(n+1,temp);
for(int i=1;i<=m;i++){
scanf("%d %d",&a,&b);
adj[a][b]=1;
adj[b][a]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<adj[i][j]<<" ";
}
cout<<endl;
}
int tot=0;
for(int i=1;i<=n;i++){
tot=0;
for(int j=1;j<=n;j++){
if(adj[i][j]==1)tot++;
}
cout<<tot<<" ";
for(int j=1;j<=n;j++){
if(adj[i][j]==1)cout<<j<<" ";
}
cout<<endl;
}
return 0;
}
图的遍历
图的遍历主要是dfs和bfs两种方式
- dfs:深度优先搜索,每次尝试都在往更深处走,主要思想是递归
- bfs:广度优先搜索,优先把同一个层次的节点走完,利用queue队列进行较为简洁的出队入队
写的也是洛谷题单里的题目:https://www.luogu.com.cn/problem/P5318
要求是分别输出dfs和bfs的结果,嗯似乎是比较板子的一道题目
一开始想用邻接矩阵来做,但是看到了题目后面有一行:
如果有很多篇文章可以参阅,请先看编号较小的那篇(因此你可能需要先排序)。
所以非常愉快的选择了邻接表,后来发现这也是正确的选择,因为节点数比较多,邻接矩阵会MLE
虽然比较板子,但还是改了好久,问题在于啊dfs和bfs忘得差不多惹以及sort和size这两个的使用。
首先来看一下sort的使用;
vector<int>adj[100010];
for(int i=1;i<=n;i++){
sort(adj[i].begin(),adj[i].end(),cmp);
}
啊对...二维vector的size还是不会,于是退而求其次用的一维vector
完整代码如下:
点击查看代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
vector<int>vis;
vector<int>adj[100010];
queue<int>q;
bool cmp(int x,int y){
return x<y;
}
void dfs(int u,int tt){
int v;vis[u]=1;
cout<<u<<" ";
if(tt==n)return;
for(int i=0;i<adj[u].size();i++){
v=adj[u][i];
if(vis[v]==0){
dfs(v,tt+1);
}
}
}
void bfs(int s){
int u,v;
q.push(s);
vis[s]=1;
cout<<s<<" ";
while(!q.empty()){
u=q.front();
for(int i=0;i<adj[u].size();i++){
v=adj[u][i];
if(vis[v]==0){
q.push(v);
cout<<v<<" ";
vis[v]=1;
}
}
q.pop();
}
}
int main(){
int u,v;
cin>>n>>m;
vis.resize(n+1,0);
for(int i=1;i<=m;i++){
cin>>u>>v;
adj[u].push_back(v);
}
for(int i=1;i<=n;i++){
sort(adj[i].begin(),adj[i].end(),cmp);
}
dfs(1,0);
cout<<endl;
for(int i=1;i<=n;i++){
vis[i]=0;
}
bfs(1);
cout<<endl;
return 0;
}
进制方面看了一下平衡三进制和各种进制间的转换以及位运算的使用
浙公网安备 33010602011771号