信息学竞赛常用模板
信息学竞赛常用模板 以及对应经典题目
01背包

1 // 经典题目 https://www.luogu.com.cn/problem/P1048 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int t[105], v[105]; 6 int dp[1005]; // 滚动数组优化的01背包 7 8 int main() { 9 int T, M; 10 cin >> T >> M; 11 for (int i = 1; i <= M; i++) { 12 cin >> t[i] >> v[i]; 13 } 14 for (int i = 1; i <= M; i++) { 15 for (int j = T; j >= 1; j--) { // 从前面转移的 所以避免一个物品被无限多次用 从后往前跑 16 if (t[i] > j) { 17 dp[j] = dp[j]; 18 } else { 19 dp[j] = max(dp[j], dp[j - t[i]] + v[i]); 20 } 21 } 22 } 23 cout << dp[T] << endl; 24 return 0; 25 }
完全背包

1 // 经典题目 https://www.luogu.com.cn/problem/P1616 2 #include <cstdio> 3 #include <iostream> 4 using namespace std; 5 6 const int N = 1e4 + 5; 7 const int M = 1e7 + 5; 8 typedef long long ll; 9 10 ll n, m, w[N], v[N], dp[M]; 11 12 int main(){ 13 scanf("%lld %lld", &m, &n); 14 for (int i = 1; i <= n; i++) 15 scanf("%lld %lld", &w[i], &v[i]); 16 for (int i = 1; i <= n; i++) 17 for (int j = w[i]; j <= m; j++) 18 dp[j] = max(dp[j], dp[j - w[i]] + v[i]); 19 printf("%lld", dp[m]); 20 return 0; 21 }
最长递增子序列

1 // 经典题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1281 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n, a[1005], ans = 0; 6 int dp[1005]; //dp[i] 1-i的最长上升子序列长度 7 8 int main() { 9 cin >> n; 10 for (int i = 1; i <= n; i++) { 11 cin >> a[i]; 12 dp[i] = 1; 13 } 14 for (int i = 1; i <= n; i++) { 15 //dp[i] 如何转移 16 for (int j = 1; j < i; j++) { 17 if (a[i] > a[j]) dp[i] = max(dp[i], dp[j] + 1); 18 } 19 ans = max(ans, dp[i]); 20 } 21 cout << ans << endl; 22 return 0; 23 }
最长公共子序列

1 // 经典题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1265 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 string s1, s2; 6 int dp[1005][1005]; 7 int main() { 8 cin >> s1 >> s2; 9 for (int i = 0; i < s1.size(); i++) { 10 for (int j = 0; j < s2.size(); j++) { 11 if (s1[i] == s2[j]) { 12 dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + 1); 13 } else { 14 dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]); 15 } 16 } 17 } 18 cout << dp[s1.size()][s2.size()] << endl; 19 return 0; 20 }
BFS走地图问题

1 // 经典题目 https://www.luogu.com.cn/problem/P1746 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 char mp[1005][1005]; // 地图 6 bool vis[1005][1005]; 7 int sx, sy, ex, ey, n; 8 int dx[4] = {0, 1, 0, -1}; 9 int dy[4] = {1, 0, -1, 0}; 10 11 struct node { // 走到的那个点坐标 和 步数 12 int x, y, step; 13 }cur; 14 queue<node> q; 15 16 void bfs() { 17 q.push(node{sx, sy, 0}); 18 vis[sx][sy] = true; 19 while (!q.empty()) { 20 cur = q.front(); 21 q.pop(); 22 if (cur.x == ex && cur.y == ey) { 23 cout << cur.step << endl; 24 return ; 25 } 26 for (int i = 0; i < 4; i++) { 27 int nx = cur.x + dx[i]; 28 int ny = cur.y + dy[i]; 29 if (vis[nx][ny] || mp[nx][ny] == '1' || nx < 1 || ny < 1 || nx > n || ny > n) { 30 continue; 31 } 32 vis[nx][ny] = true; 33 q.push(node{nx, ny, cur.step + 1}); 34 } 35 } 36 } 37 38 int main() { 39 cin >> n; 40 for (int i = 1; i <= n; i++) 41 for (int j = 1; j <= n; j++) 42 cin >> mp[i][j]; 43 cin >> sx >> sy >> ex >> ey; 44 bfs(); 45 return 0; 46 }
DFS迷宫问题

1 // 经典题目 https://www.luogu.com.cn/problem/P1605 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 // 四个方向 6 int dx[4] = {-1, 1, 0, 0}; 7 int dy[4] = {0, 0, -1, 1}; 8 int n, m, t, sx, sy, fx, fy, ans = 0; 9 bool mp[105][105]; 10 bool vis[105][105]; // 标记处理 避免来回走 导致死循环 11 12 void dfs(int x, int y) { 13 if (x == fx && y == fy) { 14 ans++; 15 return ; 16 } 17 for (int i = 0; i < 4; i++) { 18 int nx = x + dx[i]; 19 int ny = y + dy[i]; 20 // 1.不走出地图边界 2.走的点不是障碍物 3.之前没有走过 21 if (nx >= 1 && nx <= n && ny >= 1 && ny <= m 22 && !mp[nx][ny] && !vis[nx][ny]) { 23 vis[nx][ny] = true; 24 dfs(nx, ny); 25 vis[nx][ny] = false; // 回溯处理 26 } 27 } 28 } 29 30 int main() { 31 cin >> n >> m >> t; 32 cin >> sx >> sy >> fx >> fy; 33 for (int i = 1; i <= t; i++) { 34 int x, y; 35 cin >> x >> y; 36 mp[x][y] = true; // 障碍物 37 } 38 vis[sx][sy] = true; 39 dfs(sx, sy); 40 cout << ans << endl; 41 return 0; 42 }
DFS连通块问题

1 // 经典题目 https://www.luogu.com.cn/problem/P1451 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n, m; 6 char s[105][105]; 7 bool vis[105][105]; 8 int dx[4] = {-1, 1, 0, 0}; 9 int dy[4] = {0, 0, -1, 1}; 10 11 void dfs(int x, int y) { 12 for (int i = 0; i < 4; i++) { 13 int nx = x + dx[i]; 14 int ny = y + dy[i]; 15 // 1.不走出地图边界 2.不等于字符‘0’ 3.之前没有走过 16 if (!vis[nx][ny] && s[nx][ny] != '0' 17 && nx >= 1 && nx <= n && ny >= 1 && ny <= m) { 18 vis[nx][ny] = true; 19 dfs(nx, ny); 20 } 21 } 22 23 } 24 25 int main() { 26 int ans = 0; 27 cin >> n >> m; 28 for (int i = 1; i <= n; i++) { 29 for (int j = 1; j <= m; j++) { 30 cin >> s[i][j]; 31 } 32 } 33 // 整张地图遍历一遍 34 for (int i = 1; i <= n; i++) { 35 for (int j = 1; j <= m; j++) { 36 // 是数字细胞 并且还没归纳到某个数字细胞里面 37 if (s[i][j] != '0' && !vis[i][j]) { 38 ans++; 39 vis[i][j] = true; 40 dfs(i, j); 41 } 42 } 43 } 44 cout << ans << endl; 45 return 0; 46 }
埃式筛法

1 // 经典题目 https://www.luogu.com.cn/problem/P5736 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 bool is_p[1000005]; // 是否是质数 (false表示是质数) 6 int p[100005]; // 存储质数 7 8 int main(){ 9 int n, k, c = 0; 10 cin >> n; 11 is_p[0] = is_p[1] = true; 12 // 预处理 筛选出质数 13 for (int i = 2; i <= 1000000; i++) { 14 if (!is_p[i]) { // 是质数 把它的倍数筛掉 15 p[++c] = i; 16 for (int j = 2 * i; j <= 1000000; j += i) { 17 is_p[j] = true; 18 } 19 } 20 } 21 22 for (int i = 1; i <= n; i++) { 23 cin >> k; 24 if (!is_p[k]) cout << k << " "; 25 } 26 return 0; 27 }
并查集

1 // 经典题目 https://www.luogu.com.cn/problem/P1551 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int fa[5005]; 6 int fi(int x) { // 查询操作 7 if (fa[x] == x) return x; 8 else return fi(fa[x]); 9 } 10 11 void uni(int x, int y) { // 合并操作 12 int fx = fi(x), fy = fi(y); 13 if (fx != fy) { 14 fa[fx] = fy; 15 } 16 } 17 18 int main() { 19 int n, m, p; 20 cin >> n >> m >> p; 21 // 初始化 22 for (int i = 1; i <= n; i++) fa[i] = i; 23 for (int i = 1; i <= m; i++) { 24 int a, b; 25 cin >> a >> b; 26 uni(a, b); 27 } 28 for (int i = 1; i <= p; i++) { 29 int a, b; 30 cin >> a >> b; 31 if (fi(a) != fi(b)) cout << "No" << endl; 32 else cout << "Yes" << endl; 33 } 34 return 0; 35 }
最小生成树

1 // 经典题目 https://www.luogu.com.cn/problem/P1111 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int fa[100005]; 6 struct edge { 7 int u, v, w; 8 }e[200005]; 9 10 int fi(int x) { // 查询操作 11 return fa[x] == x ? x : fa[x] = fi(fa[x]); 12 } 13 14 bool cmp(edge x, edge y) { // 结构体排序 15 return x.w < y.w; 16 } 17 18 int main() { 19 int n, m, k; 20 cin >> n >> m; 21 k = n; 22 // 初始化 23 for (int i = 1; i <= n; i++) fa[i] = i; 24 for (int i = 1; i <= m; i++) { 25 cin >> e[i].u >> e[i].v >> e[i].w; 26 } 27 sort(e + 1, e + 1 + m, cmp); 28 int sum = 0; 29 for (int i = 1; i <= m; i++) { 30 int fu = fi(e[i].u); 31 int fv = fi(e[i].v); 32 if (fu != fv) { // 合并操作 33 fa[fu] = fv; 34 sum = e[i].w; 35 k--; 36 } 37 } 38 if (k == 1) cout << sum << endl; 39 else cout << -1 << endl; 40 return 0; 41 }
前缀和

1 // 经典题目 http://www.51nod.com/Challenge/Problem.html#problemId=1545 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int a[1005], b[1005]; 6 7 int main() { 8 int n, m; 9 cin >> n >> m; 10 for (int i = 1; i <= n; i++) { 11 cin >> a[i]; 12 b[i] = b[i - 1] + a[i]; // 前缀和 13 } 14 for (int i = 1; i <= m; i++) { 15 int l, r; 16 cin >> l >> r; 17 // 注意细节 要包括a[l]的值 所以拿b[l-1] 18 cout << b[r] - b[l - 1] << endl; 19 } 20 return 0; 21 }
差分

1 // 经典题目 http://www.51nod.com/Challenge/Problem.html#problemId=3113 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int ball[200005]; 6 7 int main() { 8 int n, m, a, b; 9 cin >> n >> m; 10 for (int i = 1; i <= m; i++) { 11 cin >> a >> b; 12 // 差分精髓 不直接for循环加减 13 ball[a]++; ball[b + 1]--; 14 } 15 for (int i = 1; i <= n; i++) { 16 ball[i] += ball[i - 1]; 17 cout << ball[i] << " "; 18 } 19 return 0; 20 }
二分查找

1 // 经典题目 https://www.luogu.com.cn/problem/P2249 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n, m, q, a[1000005]; 6 7 int main() { 8 cin >> n >> m; 9 for (int i = 1; i <= n; i++) cin >> a[i]; 10 for (int i = 1; i <= m; i++) { 11 cin >> q; 12 int ans = 2e9; 13 int l = 1, r = n; 14 while (l <= r) { 15 int mid = (l + r) / 2; 16 if (a[mid] == q) { 17 ans = min(ans, mid); 18 r = mid - 1; 19 } 20 else if (a[mid] > q) { 21 r = mid - 1; 22 } 23 else if (a[mid] < q) { 24 l = mid + 1; 25 } 26 } 27 if (ans == 2e9) cout << -1 << " "; 28 else cout << ans << " "; 29 } 30 return 0; 31 }
二分答案

1 // 经典题目 https://www.luogu.com.cn/problem/P1873 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 // 随着高度下降 木材增加 6 int h[1000005]; 7 8 int main() { 9 int n, m, mx = 0; 10 cin >> n >> m; 11 for (int i = 1; i <= n; i++) { 12 cin >> h[i]; 13 mx = max(mx, h[i]); 14 } 15 for (int k = mx; k >= 0; k--) { // 当前选定的高度 16 int sum = 0; 17 for (int i = 1; i <= n; i++) { 18 if (h[i] >= k) sum += (h[i] - k); 19 } 20 if (sum >= m) { 21 cout << k << endl; 22 return 0; 23 } 24 } 25 return 0; 26 }
二分图染色

1 // 经典题目 http://www.51nod.com/Challenge/Problem.html#problemId=2911 2 #include<bits/stdc++.h> 3 using namespace std; 4 5 int n, m; 6 vector<int> e[1000005]; 7 int col[1000005]; 8 9 bool dfs(int u, int c) { 10 col[u] = c; 11 for (int i = 0; i < e[u].size(); i++) { 12 int v = e[u][i]; 13 if (col[v]) { 14 if (col[v] == col[u]) return false; 15 } 16 else { 17 if (!dfs(v, -c)) return false; 18 } 19 } 20 return true; 21 } 22 23 int main() { 24 while (cin >> n >> m) { 25 for (int i = 1; i <= n; i++) { 26 e[i].clear(); 27 col[i] = 0; 28 } 29 for (int i = 1; i <= m; i++) { 30 int u, v; 31 cin >> u >> v; 32 e[u].push_back(v); 33 e[v].push_back(u); 34 } 35 if (!dfs(1, 1)) cout << "No" << endl; 36 else cout << "Yes" << endl; 37 } 38 return 0; 39 }
高精度加法

1 // 经典题目 https://www.luogu.com.cn/problem/P1601 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 // 高精度加法 6 7 string s1, s2; 8 int num1[1000], num2[1000]; 9 10 int main() { 11 cin >> s1 >> s2; 12 int n1 = s1.size(); 13 int n2 = s2.size(); 14 int n = max(n1, n2); 15 // 第一步 将数进行翻转 16 reverse(s1.begin(), s1.end()); // 字符串翻转(首地址,尾地址) 17 for (int i = 0; i < s1.size(); i++) { 18 num1[i] = (s1[i] - '0'); 19 } 20 reverse(s2.begin(), s2.end()); 21 for (int i = 0; i < s2.size(); i++) { 22 num2[i] = (s2[i] - '0'); 23 } 24 for (int i = 0; i < n; i++) { 25 if (num1[i] + num2[i] >= 10) { 26 num1[i + 1]++; 27 num1[i] -= 10; 28 } 29 num1[i] += num2[i]; 30 } 31 32 if (num1[n] > 0) cout << num1[n]; // 防止遗漏最高位进位的值 33 for (int i = n - 1; i >= 0; i--) { 34 cout << num1[i]; 35 } 36 return 0; 37 }
高进度减法

1 // 经典题目 https://www.luogu.com.cn/problem/P2142 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 string s1, s2; 6 int num1[20000], num2[20000]; 7 8 int main() { 9 cin >> s1 >> s2; 10 if (s1 == s2) { 11 cout << 0 << endl; 12 return 0; 13 } 14 int n1 = s1.size(); 15 int n2 = s2.size(); 16 bool minus = false; 17 // 字符串是按照字典序进行比较 18 // 首先比较长度 长度相同字典序比较就可以 19 if ((n1 < n2) || (n1 == n2 && s1 < s2)) { 20 minus = true; 21 swap(s1, s2); 22 swap(n1, n2); 23 } 24 25 int n = max(n1, n2); 26 for (int i = 0; i < n1; i++) { 27 num1[i] = s1[n1 - 1 - i] - '0'; 28 } 29 for (int i = 0; i < n2; i++) { 30 num2[i] = s2[n2 - 1 - i] - '0'; 31 } 32 for (int i = 0; i < n; i++) { 33 if (num1[i] - num2[i] < 0) { // 借位 34 num1[i + 1] -= 1; 35 num1[i] += 10; 36 } 37 num1[i] = num1[i] - num2[i]; 38 } 39 if (minus) cout << "-"; 40 bool f = false; // 处理前导0 41 for (int i = n - 1; i >= 0; i--) { 42 if (num1[i] > 0) f = true; 43 if (f) cout << num1[i]; 44 } 45 return 0; 46 }
结构体排序

1 // 经典题目 https://www.luogu.com.cn/problem/P1093 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 struct student { 6 int c, m, e, sum, id; 7 }; 8 student p[305]; 9 10 // 自定义排序规则 11 bool cmp(student x, student y) { 12 if (x.sum == y.sum) { 13 if (x.c == y.c) return x.id < y.id; 14 else return x.c > y.c; 15 } else { 16 return x.sum > y.sum; 17 } 18 } 19 20 int main() { 21 int n; 22 cin >> n; 23 for (int i = 1; i <= n; i++) { 24 cin >> p[i].c >> p[i].m >> p[i].e; 25 p[i].sum = p[i].c + p[i].m + p[i].e; 26 p[i].id = i; 27 } 28 sort(p + 1, p + 1 + n, cmp); 29 for (int i = 1; i <= 5; i++) { 30 cout << p[i].id << " " << p[i].sum << endl; 31 } 32 return 0; 33 }
进制转换

1 // 经典题目 https://www.luogu.com.cn/problem/P1143 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int a[105]; 6 char str[105]; 7 8 int to_10(int x, char s[]) { // 任意进制转十进制 9 int ans = 0; 10 for (int i = 0; i < strlen(s); i++) { 11 int v = 0; 12 if (s[i] >= '0' && s[i] <= '9') { 13 v = s[i] - '0'; 14 } else { 15 v = s[i] - 'A' + 10; 16 } 17 ans = ans * x + v; 18 } 19 return ans; 20 } 21 22 void to_m(int x, int m) { // 十进制转任意进制 23 int k = 0; 24 while (x) { 25 a[++k] = x % m; 26 x /= m; 27 } 28 for (int i = k; i >= 1; i--) { 29 if (a[i] < 10) cout << a[i]; 30 else cout << char(a[i] + ('A' - 10)); 31 } 32 } 33 34 int main() { 35 int n, m; 36 cin >> n >> str >> m; 37 int k = to_10(n, str); 38 to_m(k, m); 39 return 0; 40 }
拓扑排序

1 // 经典题目 https://www.luogu.com.cn/problem/P1113 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int N = 10005; 6 queue <int> q; 7 vector<int> e[N]; 8 int t[N], in[N], mx[N]; 9 int n, ans = 0; 10 11 void toposort() { 12 for (int i = 1; i <= n; i++) { 13 if (in[i] == 0) { 14 q.push(i); 15 mx[i] = t[i]; 16 } 17 } 18 while (!q.empty()) { 19 int u = q.front(); 20 q.pop(); 21 for (int i = 0; i < e[u].size(); i++) { 22 int v = e[u][i]; 23 in[v]--; 24 if (in[v] == 0) q.push(v); 25 mx[v] = max(mx[v], mx[u] + t[v]); 26 } 27 } 28 for (int i = 1; i <= n; i++) { 29 ans = max(ans, mx[i]); 30 } 31 } 32 33 int main() { 34 cin >> n; 35 for (int i = 1; i <= n; i++) { 36 int a, b, c; 37 cin >> a >> b >> c; 38 t[a] = b; 39 while (c != 0) { 40 in[a]++; 41 e[c].push_back(a); 42 cin >> c; 43 } 44 } 45 toposort(); 46 cout << ans << endl; 47 return 0; 48 }
图的深搜宽搜

1 // 经典题目 https://www.luogu.com.cn/problem/P5318 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n, m; 6 bool vis[100010]; 7 vector<int> g[100010]; 8 9 void dfs(int x, int cnt) { 10 vis[x] = true; 11 cout << x << " "; 12 if (cnt == n) return ; 13 for (int i = 0; i< g[x].size(); i++) 14 if (!vis[g[x][i]]) dfs(g[x][i], cnt + 1); 15 } 16 17 void bfs(int x) { 18 memset(vis, 0, sizeof(vis)); 19 vis[x] = true; 20 queue<int> q; 21 q.push(x); 22 while (!q.empty()) { 23 int v = q.front(); 24 q.pop(); 25 cout << v << " "; 26 for (int i = 0; i < g[v].size(); i++) { 27 if (!vis[g[v][i]]) { 28 vis[g[v][i]] = true; 29 q.push(g[v][i]); 30 } 31 } 32 } 33 } 34 35 int main() { 36 cin >> n >> m; 37 for (int i = 1; i <= m; i++) { 38 int u, v; 39 cin >> u >> v; 40 g[u].push_back(v); 41 } 42 for (int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end()); 43 dfs(1, 0); 44 cout << endl; 45 bfs(1); 46 return 0; 47 }
最短路 Floyd

1 // 经典题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1376 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int dp[105][105]; 6 const int INF = 0x3f3f3f3f; 7 8 int main() { 9 int n, m; 10 cin >> n >> m; 11 12 for (int i = 1; i <= n; i++) { // 初始化 13 for (int j = 1; j <= n; j++) { 14 if (i == j) dp[i][j] = 0; 15 else dp[i][j] = INF; 16 } 17 } 18 19 for (int i = 1; i <= m; i++) { 20 int u, v, w; 21 cin >> u >> v >> w; 22 dp[u][v] = dp[v][u] = w; // 无向图 23 } 24 25 for (int k = 1; k <= n; k++) // 中转站 26 for (int i = 1; i <= n; i++) 27 for (int j = 1; j <= n; j++) 28 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]); 29 30 int ans = 0; 31 for (int i = 1; i <= n; i++) { 32 if (dp[1][i] == INF) { 33 cout << -1 << endl; 34 return 0; 35 } else { 36 ans = max(ans, dp[1][i]); 37 } 38 } 39 cout << ans << endl; 40 41 return 0; 42 }
最短路 SPFA

1 // 经典题目 https://www.luogu.com.cn/problem/P3371 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int INF = 0x3f3f3f3f; 6 struct edge { 7 int v, w; 8 }p; 9 10 int n, m, s, u; 11 int d[10005]; // d[i]:从起点到i顶点的最短距离 12 vector<edge> e[10005]; 13 bool inque[10005]; // 优化 用数组去保持队列没有相同的点 14 15 void SPFA() { 16 queue<int> q; 17 q.push(s); 18 inque[s] = true; 19 d[s] = 0; 20 while (!q.empty()) { 21 u = q.front(); 22 q.pop(); 23 inque[u] = false; 24 for (int i = 0; i < e[u].size(); i++) { 25 p = e[u][i]; 26 if (d[p.v] > d[u] + p.w) { 27 d[p.v] = d[u] + p.w; 28 if (!inque[p.v]) q.push(p.v); 29 } 30 } 31 } 32 } 33 34 int main() { 35 cin >> n >> m >> s; 36 for (int i = 1; i <= n; i++) d[i] = INF; // 初始化 37 for (int i = 1; i <= m; i++) { 38 cin >> u >> p.v >> p.w; 39 e[u].push_back(p); // 有向图 40 } 41 SPFA(); 42 for (int i = 1; i <= n; i++) cout << d[i] << " "; 43 return 0; 44 }
最短路 Dijkstra

1 // 经典题目 https://www.luogu.com.cn/problem/P4779 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int N = 100005; 6 const int INF = 0x3f3f3f3f; 7 vector< pair<int, int> > e[N]; // 邻接表存图 8 int n, m, s, d[N]; 9 bool vis[N]; 10 11 void dijkstra() { 12 // 优先队列 注意和e里面存的东西进行区分 13 priority_queue< pair<int, int> > q; 14 // 初始化 15 for (int i = 0; i <= n; i++) d[i] = INF; 16 d[s] = 0; 17 q.push(make_pair(0, s)); 18 while (!q.empty()) { 19 int u = q.top().second; 20 q.pop(); 21 if (vis[u]) continue; 22 vis[u] = true; // 出来的时候一定是u离起点最近的距离 23 for (int i = 0; i < e[u].size(); i++) { 24 int v = e[u][i].first; 25 int w = e[u][i].second; 26 if (d[u] + w < d[v]) { 27 d[v] = d[u] + w; 28 q.push(make_pair(-d[v], v)); 29 } 30 } 31 } 32 } 33 34 int main() { 35 cin >> n >> m >> s; 36 for (int i = 1; i <= m; i++) { 37 int u, v, w; 38 cin >> u >> v >> w; 39 e[u].push_back(make_pair(v, w)); 40 } 41 dijkstra(); 42 for (int i = 1; i <= n; i++) cout << d[i] << " "; 43 return 0; 44 }
LCA

1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, m, s, ans; 4 vector<int> e[500005]; 5 int dep[500005]; 6 bool vis[500005]; 7 int fa[500005]; 8 9 void find(int p, int deep) { 10 dep[p] = deep; 11 for (int i = 0; i < e[p].size(); i++) { 12 if (!vis[e[p][i]]) { 13 fa[e[p][i]] = p; 14 vis[e[p][i]] = true; 15 find(e[p][i], deep + 1); 16 } 17 } 18 } 19 20 void dfs(int a, int b) { 21 if (dep[a] > dep[b]) { 22 dfs(fa[a], b); 23 } else if (dep[a] < dep[b]) { 24 dfs(a, fa[b]); 25 } else if (dep[a] == dep[b]) { 26 if (a == b) { 27 ans = a; 28 return; 29 } 30 else { 31 dfs(fa[a], fa[b]); 32 } 33 } 34 } 35 36 int main() { 37 scanf("%d%d%d", &n, &m, &s); 38 for (int i = 1; i <= n - 1; i++) { 39 int x, y; 40 scanf("%d%d", &x, &y); 41 e[x].push_back(y); 42 e[y].push_back(x); 43 } 44 vis[s] = true; 45 find(s, 1); 46 while (m--) { 47 int a, b; 48 scanf("%d%d", &a,&b); 49 dfs(a, b); 50 printf("%d\n", ans); 51 } 52 return 0; 53 }
快速幂

1 // 经典题目 https://www.luogu.com.cn/problem/P1226 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 typedef long long ll; 6 7 int main() { 8 ll a, b, p, res = 1; 9 cin >> a >> b >> p; 10 cout << a << "^" << b << " mod " << p << "="; 11 while (b) { 12 if (b % 2) res = (res * a) % p; 13 b /= 2; 14 a = (a * a) % p; 15 } 16 cout << res; 17 return 0; 18 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现