CSP-S 考前复习
2025-10-26 13:56:09
发布于:上海
1 三种最短路算法
Dijkstra
dijkstra堆优化版本_信奥算法普及/提高--ACGO题库
#include<bits/stdc++.h>
using namespace std;
int n,m,s = 1,u,v,w;
const int N = 1e5 + 10;
int dis[N],vis[N];
struct edge{
int dis,v;
friend bool operator < (edge a,edge b){
return a.dis > b.dis;
}
};
priority_queue<edge> q;
struct Node{
int weight,to;
};
vector<Node> g[N];
void dij(){
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
q.push({0,s});
while(!q.empty()){
edge t = q.top();
q.pop();
int x = t.v;
if(vis[x] == 1) continue;
vis[x] = 1;
for(int j = 0;j < g[x].size();j++){
int y = g[x][j].to;
int w = g[x][j].weight;
if(dis[y] > dis[x] + w){
dis[y] = dis[x] + w;
q.push({dis[y],y});
}
}
}
}
int main(){
cin >> n >> m;
for(int i = 1;i <= m;i++){
cin >> u >> v >> w;
g[u].push_back({w,v});
}dij();
for(int i = 1;i <= n;i++){
cout << dis[i] << " ";
}
return 0;
}
SPFA
#include<bits/stdc++.h>
using namespace std;
struct Node {
int z, q;
};
vector<Node>v[100005];
int dis[100005];
bool vis[100005];
queue<int>q;
int main() {
int n, m, s, t;
cin >> n >> m >> s >> t;
for (int i = 1; i <= m; i++) {
int x, y, z;
cin >> x >> y >> z;
v[x].push_back({ y,z });
}
for (int i = 0; i <= n + 1; i++) {
dis[i] = 1e9;
}
dis[s] = 0;
vis[s] = 1;
q.push(s);
while (!q.empty()) {
int k = q.front();
q.pop();
vis[k] = 0;
for (int i = 0; i < v[k].size(); i++) {
int to = v[k][i].z;
int len = v[k][i].q;
if (dis[to] > dis[k] + len) {
dis[to] = dis[k] + len;
if (!vis[to]) {
vis[to] = 1;
q.push(to);
}
}
}
}
cout << dis[t];
return 0;
}
Floyd
最短距离查询【Floyd】_信奥算法入门_官方-ACGO题库
#include<bits/stdc++.h>
using namespace std;
int dis[205][205];
int main() {
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = 1e9;
}
}
for (int i = 1; i <= m; i++) {
int x, y, z;
cin >> x >> y >> z;
dis[x][y] = z;
}
for (int kk = 1; kk <= n; kk++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = min(dis[i][j], dis[i][kk] + dis[kk][j]);
}
}
}
for (int i = 1; i <= k; i++) {
int x, y;
cin >> x >> y;
dis[x][y] == 1e9 ? cout << "impossible" << '\n' : cout << dis[x][y] << '\n';
}
return 0;
}
2 几种背包
见【线性DP】问题模型总结
3 ST表和LCA
ST表
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10, M = 50;
int a[N];
int f[N][M];
int find(int l, int r) {
int k = log2(r + 1 - l);
return min(f[l][k], f[r - (1 << k) + 1][k]);
}
int main() {
int m, n;
cin >> m >> n;
for (int i = 1; i <= m; i++) {
cin >> a[i];
}
for (int i = 1; i <= m; i++) {
f[i][0] = a[i];
}
int k = log2(m);
for (int j = 1; j <= k; j++) {
for (int i = 1; i <= m + 1 - (1 << j); i++) {
f[i][j] = min(f[i][j - 1], f[(1 << (j - 1)) + i][j - 1]);
}
}
while (n--) {
int a, b;
cin >> a >> b;
cout << find(a, b) << " ";
}
}
LCA
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, s;
vector<int> g[N];
int fat[N][20];//fa[u][i]:从u结点,跳2^i步的结点
int dep[N];//存储深度
void dfs(int now, int fa){
fat[now][0] = fa;
dep[now] = dep[fa] + 1;
for(int i = 1; i <= 19; i++){
fat[now][i] = fat[fat[now][i - 1]][i - 1];
}
for(auto v : g[now]){
//避免往上跳
if(v == fa) continue;
dfs(v, now);
}
}
int LCA(int x, int y){
//1、先将x,y跳到同一层
//不妨设dep[x] >= dep[y]
if(dep[x] < dep[y]) swap(x, y);
int dis = dep[x] - dep[y];
for(int i = 0; i <= 19; i++){
if(dis >> i & 1) x = fat[x][i];
}
if(x == y) return x;
//2、一起跳到LCA的下一层
for(int i = 19; i >= 0; i--){
//因为要跳到LCA的下一层,所以一定是不相等的
if(fat[x][i] != fat[y][i]){
x = fat[x][i], y = fat[y][i];
}
}
return fat[x][0];
}
int main(){
cin >> n >> m >> s;
for(int i = 1; i <= n - 1; i++){
int u, v;
cin >> u >> v;
g[u].push_back(v), g[v].push_back(u);
}
dfs(s, 0);
while(m--){
int a, b;
cin >> a >> b;
cout << LCA(a,b) << endl;//+_+
}
// for(int i = 1; i <= n; i++){
// for(int j = 0; j < 20; j++){
// cout << fat[i][j] << " ";
// }
// cout << endl;
// }
return 0;
}
/*
1、处理出深度数组
2、处理出存储跳了2^i步的父亲结点 ST表
3、利用ST表求LCA
9 1 1
1 5
1 4
5 2
5 6
5 7
6 3
6 8
3 9
*/
4 归并排序,找逆序对
归并排序
#include<iostream>
using namespace std;
int n;
int m[1050];
void sort(int la, int ra, int lb, int rb) {
int i = la, j = lb, cnt = 0;
int srt[1050];
while (i <= ra && j <= rb) {
if (m[i] <= m[j]) srt[++cnt] = m[i++];
else srt[++cnt] = m[j++];
}
while (i <= ra) srt[++cnt] = m[i++];
while (j <= rb) srt[++cnt] = m[j++];
for (int i = 1; i <= cnt; i++) m[la + i - 1] = srt[i];
return;
}
void merge(int l, int r) {
if (l >= r) return;
int mid = (l + r) >> 1;
merge(l, mid);
merge(mid + 1, r);
sort(l, mid, mid + 1, r);
for (int i = 1; i <= n; i++) cout << m[i] << ' ';
cout << endl;
return;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> m[i];
merge(1, n);
return 0;
}
逆序对
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
long long ans;
int a[N], temp[N];
int n;
void merge(int l, int mid, int r) {
int i = l, j = mid + 1, k = l;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) temp[k++] = a[i++];
else {
temp[k++] = a[j++];
ans += mid - i + 1;
}
}
while (i <= mid) {
temp[k++] = a[i++];;
}
while (j <= r) {
temp[k++] = a[j++];
}
for (int g = l; g <= r; g++) {
a[g] = temp[g];
}
}
void merge_sort(int l, int r) {
if (l >= r) {
return;
}
int mid = (l + r) / 2;
merge_sort(l, mid);
merge_sort(mid + 1, r);
merge(l, mid, r);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
merge_sort(1, n);
cout << ans << endl;
}
5 拓扑排序
#include<bits/stdc++.h>
using namespace std;
const int N = 100000 + 10;
int n, m;
vector<int> g[N];
int in[N];
long long f[N];
int k[N];
queue<int> q;
void bfs() {
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i : g[u]) {
in[i]--;
f[i] += f[u];
if (!in[i]) {
q.push(i);
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
in[y]++;
k[x]++;
}
for (int i = 1; i <= n; i++) {
if (!in[i] && g[i].size()) {
f[i] = 1;
q.push(i);
}
}
bfs();
long long cnt = 0;
for (int i = 1; i <= n; i++) {
if (!k[i])
cnt += f[i];
}
cout << cnt;
}
6 STL容器的常用用法
(太多了,自己翻笔记去
这里空空如也












有帮助,赞一个