考前必会知识点
CSPJ
文章目录
1. dijkstra
算法的堆优化实现
struct node
{
int u, dis;
inline bool operator < (const node & cmp2) const
{
return dis > cmp2.dis;
}
} ;
typedef size_t SIZE;
SIZE d[constexpr max(s, t)];
SIZE dijkstra(int s, int t)
{
priority_queue <node> q;
memset (d, 0x3f, sizeof d);
d[1] = 0; // d[1] 的长度默认为 0
node t;
t.u = s; // 从s点开始
t.dis = 0; // 初始距离为 0
q.push(t);
while (! q.empty())
{
node t = q.top(); // 头结点
q.pop();
int u = t.u;
for (i : 枚举每一条邻接边)
{
int v = to[i];
if (d[u] + w[i] < d[v])
{
d[v] = d[u] + w[i];
node g;
g.dis = d[v];
g.u = v;
q.push(g);
}
}
}
return d[t];
}
2. Bellman_ford
算法
int bellman(int s, int t)
{
// 定义 n 是点数,m 是边数
memset(d, 0x3f, sizeof d);
d[s] = 0;
for (int step = 1; step < n; step ++) // 枚举步数
for (int i = 1; i <= m; i ++)
if (d[edge[i].a] + edge[i].c < d[edge[i].b]) // 更新答案
d[edge[i].b] = d[edge[i].a] + edge[i].c;
return d[t];
}
3. Kruskal
算法
void kruskal(Edge * edge) // edge代表所有的边
{
// n是点数,m是边数
init_fa(); // 初始化并查集
int cnt = 0, ret = 0;
for (int i = 1; i <= m; i ++)
{
int ta = find_fa(edge[i].a); // find_fa: 查找某一个点的最远父亲是谁
int tb = find_fa(edge[i].b);
if (ta != tb)
Union_fa(ta, tb), cnt ++, ret += c; // Union_fa: 合并并查集中的某两个点
}
if (cnt != n - 1) // 出现错误(比如说图不连通)
return -1;
return ret;
}
4. STL
基本操作
// 1. map
map <typename, typename> d; // 定义一个叫做d,将第一个类型映射到第二个类型的容器
d[] = []; // 设置某一个位置的值
unordered_map <typename, typename> d; // 要求编译器>=C++11
// 2. set
set <typename> s; // 定义一个类型为typename的集合
s.count(v); // 统计v出现过的次数
s.find(v); // 统计v第一次出现的位置
s.begin() / s.end(); // 开始位置和结束位置,左闭右开
s.find_last_of(); // 查找最后一次的位置
s.find_first_of(); // 查找第一次出现的位置
s.upper_bound(); // 查找第一个大于某一个数的位置
s.lower_bound(); // 查找第一个大于等于某一个数的位置
multiset <typename> s; // 可重集合
unordered_set <typename> s; // 要求编译器>=C++11
// 3. priority_queue
priority_queue <typename> pq; // 优先队列,小根堆
pq.push(); // 插入元素
pq.pop(); // 弹出元素
pq.top(); // 对首元素
pq.size(); // 队列大小
pq.empty(); // 判断是否为空
pq.swap(); // 交换,如果编译器<C++11,那么时间复杂度为O(N),否则为O(1)。慎用!
priority_queue <typename, vector <typename>, greater <typename> > // 大根堆
5. floyd
算法
void floyd(two_array mp); // two_array 代表二维数组
{
for (int k = 1; k <= n; k ++)
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]); // 枚举中转点k
}
6. 拓扑排序
bool top_sort()
{
int hh = 0, tt = -1;
for (int i = 1; i <= n; i ++)
if (! d[i])
q[++ tt] = i;
while (hh <= tt)
{
int t = q[hh ++];
for (i是t的所有邻接点)
{
int v = to[i];
d[v] --; // d代表v点的入度数量,删除所有和i邻接的点
if (! d[j])
q[++ tt] = j;
}
}
}
7. 哈希表
vector <int> h[1000010]; // 暂且不用管vector是什么
inline void Insert(int p)
{
h[p % 1000007].push_back(p);
}
bool find(int x)
{
for (int i = 0; i < h[x % 1000007].size(); i ++)
if (a[h][i] == x)
return true;
return false;
}