5.31 专业课复习笔记 12
昨天想着每天下午复习专业课,但是我发现限制得太严格还是不太合适。慢慢学吧就。
感觉为了防止学习疲劳,可以学两个小时专业课,然后学两个小时数学。看视频或者看书的时候专心看。1.5 倍速看视频(我发现我还是适合正常速度看)。
并查集自己之前学过。算了,我也别考虑每天都要学四门课了,就是学专业课,学累了就学数学,政治,英语这样子,乱学就可以了。没啥问题。不然心理压力太大了,我根本就平衡不了,不考虑平衡了。all in 就行了。(发现加粗可以让阅读体验更好一些。以后可以多使用。)并查集就是给具有相同属性的元素放到一个集合里面,每个元素都是直接建立和根节点的关系,就是比如说,每个员工知道自己的公司的 CEO 是谁,应该大概是这个意思吧。
F l o y d − w a r s h a l l Floyd-warshall Floyd−warshall 算法:看起来好像是动态规划,但是我完全看不懂呢。废了废了。下面是 y 总的基础课里面给的代码。我在准备初试的时候,可以把基础课里面的代码好好学一学。感觉没啥坏处。
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 210, INF = 1e9;int n, m, Q;
int d[N][N];void floyd()
{for (int k = 1; k <= n; k ++ )for (int i = 1; i <= n; i ++ )for (int j = 1; j <= n; j ++ )d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}int main()
{scanf("%d%d%d", &n, &m, &Q);for (int i = 1; i <= n; i ++ )for (int j = 1; j <= n; j ++ )if (i == j) d[i][j] = 0;else d[i][j] = INF;while (m -- ){int a, b, c;scanf("%d%d%d", &a, &b, &c);d[a][b] = min(d[a][b], c);}floyd();while (Q -- ){int a, b;scanf("%d%d", &a, &b);int t = d[a][b];if (t > INF / 2) puts("impossible");else printf("%d\n", t);}return 0;
}
可恶,我要是看不懂就记下来。没啥大不了的。另外不要递归,拓展地去学习,这样下去没完没了,也抓不住重点,这是应试。应试的本质提分。
图是由顶点和边组成的。v 表示顶点,e 表示边。研究的重点主要是有向图,因为无向图和混合图都可以转换为有向图。这样可以让我们的研究更加简洁。对于无向图,连接了多少条边,就可以认为,这个点的度是多少。简单图是不包含自环的图,也是研究重点。
沿途边的总数,定义为通路的长度。欧拉环路是所有边刚好经过一次,然后环路的长度等于边数。边的上界是 O ( n 2 ) O(n^2) O(n2) ,假设顶点的个数是 n ,这个是因为,分为两种情况讨论,假设是无向图,那么,两个点之间只能是最多一条边,我们就是讨论边最多的情况,一个点可以和剩下的 n - 1 个点之间连一条边,n 个点都可以和除了自己的 n - 1 个点连接,所以边的上限是 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1) ,除以 2 是因为,多算了一次,A 和 B 连接和 B 和 A 连接本质上是同一条边。有向图的话,上限就是 n ( n - 1 ),我们考虑数量级的时候,是不考虑常系数的。所以可以认为,边数的上限就是顶点数目的平方的级别。
看到一个网友考研七年三百分的实力都没有,我很害怕,我害怕成为这样的人。感觉他就是没有花时间研究具体的考研初试的问题,不然怎么可能考不到三百分呢。晚饭之后去散步了几圈,想了一下,多总结是有道理的。我得多多总结。总结之后才能逃避内卷,因为总结就是在强迫自己思考,而不是做一些简单重复的事情。我们需要的是强度,因为纯粹的堆叠时间,二战三战的人赢麻了。我非常好奇,这些代码,真的有人可以很轻松地看懂么,我看这些东西真的感觉看天书一样。或者有的代码感觉就是没啥实际的意义,就只是定义了一下,但是没有看到里面的具体的逻辑部分。我现在需要做的是了解这个东西的概念和逻辑,而不是代码里面的底层实现。因为底层的代码实现,太有挑战性了。并且容易陷入到纠结一些小细节里面去。
邻接矩阵的实现里面,对于一般的操作都是常数时间复杂度的,顶点的动态操作的分摊时间复杂度是线性的。 空间复杂度就是平方级别的。因为使用的是二维向量存储的顶点之间的关系。顶点之间的关系实际上就是边。无向图的邻接矩阵是对称阵,可以压缩,进一步降低空间复杂度,但是应该也只是改进一下常系数。邻接表表示的实际也比较简单,就是,左边是根节点,可以理解为根节点,或者是手电筒的光源吧,这个光源可以发射光线,射到的点,写在右边,右边的点都是直接和最左边的点相连的。写到这里想到了 “ x t u o j xtu \ oj xtu oj 神经网络” 这个题,呜呜呜。
邻接表的空间总量是线性级别的。相比于邻接矩阵的平方级别的空间总量,改进了一个线性因子。改进空间复杂度,可能就要增加某些操作的时间复杂度。判断两个点之间有没有边,需要从最左边扫描到最右边,最坏情况是扫描到最右边,所以需要的时间复杂度是线性的。邻接矩阵进行这个操作只需要常数时间,因为数组具有随机访问的特点。总结就是邻接表牛逼,用邻接表就完事了。
从今天开始,晚上十一点睡觉,别睡得太早了,也别睡得太晚了。 图搜索的时间复杂度是线性的,因为我们需要搜索每个点和每条边,所以这就是最优的算法了。广度有限搜索和树的层次遍历是一个效果。
下面是 y 总写的广度优先搜索的模板。我找个时间把图论的基础的算法给练习一下。主要是把一些基本的模板给练习一下。书上说的所谓的波峰集我感觉是一个更高层次的理解,我知道这个东西大概是什么意思就好了。这个广度优先搜索,用考研复习来理解就是,每次学一个科目的一点点,然后就换科目,然后不断循环,最后也能把四个科目的所有知识点学完。但是这样复习考研不是那么爽。我现在比较喜欢一个科目学到很爽之后再换另一个科目学。妈的有些代码写得太简洁了,哪怕写了注释我都看着害怕。
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>using namespace std;typedef pair<int, int> PII;const int N = 110;int n, m;
int g[N][N], d[N][N];int bfs()
{queue<PII> q;memset(d, -1, sizeof d);d[0][0] = 0;q.push({0, 0});int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};while (q.size()){auto t = q.front();q.pop();for (int i = 0; i < 4; i ++ ){int x = t.first + dx[i], y = t.second + dy[i];if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1){d[x][y] = d[t.first][t.second] + 1;q.push({x, y});}}}return d[n - 1][m - 1];
}int main()
{cin >> n >> m;for (int i = 0; i < n; i ++ )for (int j = 0; j < m; j ++ )cin >> g[i][j];cout << bfs() << endl;return 0;
}
下面是我对于广度优先搜索的代码的一些理解。感觉基本废了。看书上的代码基本上串不起来。也不知道具体是哪里看不懂。都不知道怎么请教别人。有点无力。算了我不想看书了。很多东西都不知道,细节太多了。还是去看视频了。
算了,今天不学专业课了。算是图部分开了个头,探索了一下适合自己的学习模式。也算不错。