Day 1 高中部寒假集训
Day1:
emming,高中部集训在春节前要上5天,春节后上2天(如果我没记错的话QAQ)。
学校的电脑系统重装了一遍,把万恶的冰点还原(^-^)和教师监控系统(但是我怎么接老师课件啊QAQ)刷掉了,嘿嘿嘿。
以上是废话。
今天课程表:
2019.1.23
上午
- 数学:排列组合、概率论、素数筛、快速幂、欧几里得算法、扩欧。
下午
- 图论:基本概念、储存方式、遍历方式、拓扑排序、最短路。
晚上
- 考试
笔记
1. 概率论
- 概率空间:
- 定义:一般我们在一个概率空间内探讨问题,概率空间即所有可能事件的集合,每一件事件有确定的概率。
- 性质:表示,同时发生的概率,表示在已经发生的情况下,A发生的概率,又叫条件概率。
- 期望:
- 定义:随机变量,概率空间中的事件为变量的取值情况,的期望,即所有取值的加权平均,意义为对一个随机变量进行观测后的可能值叠加。
- 期望的线性性:
- 若,两个变量独立,则
2.拓扑排序
对象:有向无环图。
作用:将一个图G中的所有顶点排序成一个序列,使得对于图中每一条边,满足在序列中排在的前面(便利顺序),这个序列被称为图的拓扑序列。
算法:
- 从图中任选一个入度为 0 的顶点,加入拓扑序列末端
- 删除这个顶点及其所有出边
- 回到 S1 继续执行,直到图中没有顶点
结论:任意 可经由拓扑排序化为合法的拓扑序列。
拓展:
可以用在图中检验是否含有环,方法是拓扑排序后检查是否有未标记完的顶点。如果有,就说明有环,因为环使得不会有一个顶点入度为0。
时间复杂度:
邻接表:
邻接矩阵:
例题:2883 奇怪的梦境
分析:判断是否可以按下全部按钮就是判段有向图中是否存在环,使用拓扑排序可以判断。
- :
#include <iostream> #include <cstdio> using namespace std; struct node{ int v,next;//使用邻接表存边 }edge[25005]; int n,m,head[10005],cnt,deg[10005]; bool book[10005]; inline void add(int u,int v){ cnt++; edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt; return; } int main(){ int a,b; scanf("%d%d",&n,&m); for (int i=1;i<=m;i++){ scanf("%d%d",&a,&b); add(a,b); deg[b]++; } for (int i=1;i<=n;i++){ int start=-1; for (int j=1;j<=n;j++) if (!book[j]&°[j]==0){ start=j; book[j]=true; break; } if (start==-1){ cout <<"T_T"<<endl<<n-i+1<<endl; return 0; } for (int j=head[start];j!=0;j=edge[j].next) deg[edge[j].v]--; } cout <<"o(∩_∩)o"<<endl; return 0; }
3. 最短路
单源最短路,对于给定带权图(有向或无向),计算从源点到其它所有顶点的最短路径。
“三角形性质”:设源点s到u, v最短路径长度分别为 与间距离为 ,则有:。
松弛:若在处理过程中,有两点不满足“三角形性质”,则可作改进:
if (dis[u] + len[u][v] < dis[v]) dis[v] = dis[u] + len[u][v];
- 算法:
- 算法:将图中顶点分为两个集合, ,由已求出最短路的顶点组成,由其他顶点组成,初始时为空,记源点到每个点最短路径为,初始时,其余点。
- 从集合中取出一个当前距离最近的点
- 将从中剔除、加入集合,并对与相邻的顶点试作松弛
- 若 ,则算法结束,否则转至第1步。
- 伪代码:
void dijkstra(int s){ 置dis初值; 循环n次{ 找到B集合中dis最小的点v; 将v从B中剔除、加入A; 用v对其相邻点试作松弛; } }
- 时间复杂度
- :使用循环确定松弛顶点。
- :使用优先队列。
- 对象:
- 有向图、无向图(无向图看做两点两条有向边)
- 有环或无环
- 不可有负权边
- 算法:将图中顶点分为两个集合, ,由已求出最短路的顶点组成,由其他顶点组成,初始时为空,记源点到每个点最短路径为,初始时,其余点。
- 算法
- 算法:对每条边 ,进行松弛:,共循环次。
- 时间复杂度:
- 对象:相比算法可出现负权值、负环。
- 扩展:
- 判断负权环:最后判断是否存在边,使得 。
- 算法,算法的一种队列改进:
- 优化:
- 采用队列存放用来更新其它点dis值的点
- 当一个点的值被更新时,就将它加入队列
- 如果队列中已有这个点,则不用加入
- 时间复杂度:最坏,平均
- 优化:
多源最短路:对于给定带权图(有向或无向),计算所有顶点间两两最短路径。
- 算法
算法:有一些的思想->_<-,表示从到只经过前个点的最短路径。初始状态:,。
转移方程:, 即所求。
- 算法**核心代码**:
for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
时间复杂度:
- 算法
总结
今天的考试有点难,或者说码量比较大,说明我还是太菜了QAQ