(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)

简介: (万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)

(三) 搜索和图论



树与图的存储

树是一种特殊的图,与图的存储方式相同。

对于无向图中的边ab,存储两条有向边a->b, b->a。

因此我们可以只考虑有向图的存储。

(1) 邻接矩阵:g[a][b] 存储边a->b

(2) 邻接表:

// 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点
int h[N], e[N], ne[N], idx;
// 添加一条边a->b
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
// 初始化
idx = 0;
memset(h, -1, sizeof h);

1.DFS


int dfs(int u)//模板
{
    st[u] = true; // st[u] 表示点u已经被遍历过
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}


2.BFS


queue<int> q;//模板
st[1] = true; // 表示1号点已经被遍历过
q.push(1);
while (q.size())
{
    int t = q.front();
    q.pop();
    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}


3.树与图的深度优先遍历


int dfs(int u)//模板
{
    st[u] = true; // st[u] 表示点u已经被遍历过
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}


4.树与图的广度优先遍历


queue<int> q;//模板
st[1] = true; // 表示1号点已经被遍历过
q.push(1);
while (q.size())
{
    int t = q.front();
    q.pop();
    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}


5.拓扑排序


bool topsort()
{
    int hh = 0, tt = -1;
    // d[i] 存储点i的入度
    for (int i = 1; i <= n; i ++ )
        if (!d[i])
            q[ ++ tt] = i;
    while (hh <= tt)
    {
        int t = q[hh ++ ];
        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0)
                q[ ++ tt] = j;
        }
    }
    // 如果所有点都入队了,说明存在拓扑序列;否则不存在拓扑序列。
    return tt == n - 1;
}


6.Dijkstra


1.朴素版dijkstra
时间复杂是 O(n^2+m), n 表示点数,m 表示边数
int g[N][N];  // 存储每条边
int dist[N];  // 存储1号点到每个点的最短距离
bool st[N];   // 存储每个点的最短路是否已经确定
// 求1号点到n号点的最短路,如果不存在则返回-1
int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    for (int i = 0; i < n - 1; i ++ )
    {
        int t = -1;     // 在还未确定最短路的点中,寻找距离最小的点
        for (int j = 1; j <= n; j ++ )
            if (!st[j] && (t == -1 || dist[t] > dist[j]))
                t = j;
        // 用t更新其他点的距离
        for (int j = 1; j <= n; j ++ )
            dist[j] = min(dist[j], dist[t] + g[t][j]);
        st[t] = true;
    }
    if (dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}
2.堆优化版dijkstra
typedef pair<int, int> PII;
int n;      // 点的数量
int h[N], w[N], e[N], ne[N], idx;       // 邻接表存储所有边
int dist[N];        // 存储所有点到1号点的距离
bool st[N];     // 存储每个点的最短距离是否已确定
// 求1号点到n号点的最短距离,如果不存在,则返回-1
int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, 1});      // first存储距离,second存储节点编号
    while (heap.size())
    {
        auto t = heap.top();
        heap.pop();
        int ver = t.second, distance = t.first;
        if (st[ver]) continue;
        st[ver] = true;
        for (int i = h[ver]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > distance + w[i])
            {
                dist[j] = distance + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    if (dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}


7.bellman-ford

8.spfa

9.Floyd

10.Prim

11.Kruskal

12.染色法判定二分图

13.匈牙利算法


(四)数学/数论知识



1.质数

2.约数

3.欧拉函数

4.快速幂

5.扩展欧几里得算法

6.中国剩余定理

7.高斯消元

8.求组合数

9.容斥定理

10.简单博弈论


(五)动态规划



1.背包问题

2.线性dp

3.区间dp

4.计数类dp

5.数位统计dp

6.状态压缩dp

7.树形dp

8.记忆化搜索


(六)简单版贪心



1.区间贪心类

2.Huffman树

3.排序不等式

4绝对值不等式

5.推公式


(七)C++的STL简介



1.vector, 变长数组,倍增的思想


   size()  返回元素个数

   empty()  返回是否为空

   clear()  清空

   front()/back()

   push_back()/pop_back()

   begin()/end()

   支持比较运算,按字典序


2.pair<int, int>


   first, 第一个元素

   second, 第二个元素

   支持比较运算,以first为第一关键字,以second为第二关键字(字典序)


3.string,字符串


   size()/length()  返回字符串长度

   empty()

   clear()

   substr(起始下标,(子串长度))  返回子串

   c_str()  返回字符串所在字符数组的起始地址


4.queue, 队列


   size()

   empty()

   push()  向队尾插入一个元素

   front()  返回队头元素

   back()  返回队尾元素

   pop()  弹出队头元素


5.priority_queue, 优先队列,默认是大根堆


   size()

   empty()

   push()  插入一个元素

   top()  返回堆顶元素

   pop()  弹出堆顶元素

   定义成小根堆的方式:priority_queue<int, vector<int>, greater<int>> q;


6.stack, 栈


   size()

   empty()

   push()  向栈顶插入一个元素

   top()  返回栈顶元素

   pop()  弹出栈顶元素


7.deque, 双端队列


   size()

   empty()

   clear()

   front()/back()

   push_back()/pop_back()

   push_front()/pop_front()

   begin()/end()


8.set, map, multiset, multimap, 基于平衡二叉树(红黑树),动态维护有序序列


   size()

   empty()

   clear()

   begin()/end()

   ++, -- 返回前驱和后继,时间复杂度 O(logn)


 set/multiset


       insert()  插入一个数

       find()  查找一个数

       count()  返回某一个数的个数

      erase()

           (1) 输入是一个数x,删除所有x   O(k + logn)

           (2) 输入一个迭代器,删除这个迭代器

       lower_bound()/upper_bound()

           lower_bound(x)  返回大于等于x的最小的数的迭代器

           upper_bound(x)  返回大于x的最小的数的迭代器


 map/multimap


       insert()  插入的数是一个pair

       erase()  输入的参数是pair或者迭代器

       find()

       注意multimap不支持此操作。 时间复杂度是 O(logn)

       lower_bound()/upper_bound()


unordered_set, unordered_map, unordered_multiset, unordered_multimap, 哈希表

   和上面类似,增删改查的时间复杂度是 O(1)

   不支持 lower_bound()/upper_bound(), 迭代器的++,--


bitset, 圧位


   bitset<10000> s;

   ~, &, |, ^

   >>, <<

   ==, !=

   count()  返回有多少个1

   any()  判断是否至少有一个1

   none()  判断是否全为0


   set()  把所有位置成1

   set(k, v)  将第k位变成v

   reset()  把所有位变成0

   flip()  等价于~

   flip(k) 把第k位取反


相关文章
|
1月前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
1月前
|
存储 机器学习/深度学习 编解码
双选择性信道下正交啁啾分复用(OCDM)的低复杂度均衡算法研究——论文阅读
本文提出统一相位正交啁啾分复用(UP-OCDM)方案,利用循环矩阵特性设计两种低复杂度均衡算法:基于带状近似的LDL^H分解和基于BEM的迭代LSQR,将复杂度由$O(N^3)$降至$O(NQ^2)$或$O(iNM\log N)$,在双选择性信道下显著提升高频谱效率与抗多普勒性能。
163 0
双选择性信道下正交啁啾分复用(OCDM)的低复杂度均衡算法研究——论文阅读
|
2月前
|
传感器 资源调度 算法
DDMA-MIMO雷达多子带相干累积目标检测算法——论文阅读
本文提出一种多子带相干累积(MSCA)算法,通过引入空带和子带相干处理,解决DDMA-MIMO雷达的多普勒模糊与能量分散问题。该方法在低信噪比下显著提升检测性能,实测验证可有效恢复目标速度,适用于车载雷达高精度感知。
424 4
DDMA-MIMO雷达多子带相干累积目标检测算法——论文阅读
|
1月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
8月前
|
算法 安全 搜索推荐
套用算法模板备案审核问题增多的原因及解决建议
随着算法备案要求的完善,企业常因使用网上廉价模板而遭遇审核通过率低、问题增多的困境。本文分析了审核不通过的原因,包括模板缺乏针对性、审核标准严格、审核人员主观差异及企业准备不足等,并提出建议:深入了解备案要求、准备详尽材料、避免通用模板、寻求专业帮助。备案后还需持续合规管理,确保算法服务安全运行。
|
机器学习/深度学习 安全 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
|
安全 搜索推荐 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
|
自然语言处理 搜索推荐 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(下)
|
机器学习/深度学习 人工智能 自然语言处理
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(上)
|
机器学习/深度学习 人工智能 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(下)

热门文章

最新文章