信息学竞赛常用模板

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

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 }
View Code
复制代码

完全背包

复制代码
 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 }
View Code
复制代码

最长递增子序列

复制代码
 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 }
View Code
复制代码

最长公共子序列

复制代码
 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 }
View Code
复制代码

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 }
View Code
复制代码

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 }
View Code
复制代码

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 }
View Code
复制代码

埃式筛法

复制代码
 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 }
View Code
复制代码

并查集

复制代码
 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 }
View Code
复制代码

最小生成树

复制代码
 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 }
View Code
复制代码

前缀和

复制代码
 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 }
View Code
复制代码

差分

复制代码
 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 }
View Code
复制代码

二分查找

复制代码
 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 }
View Code
复制代码

二分答案

复制代码
 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 }
View Code
复制代码

二分图染色

复制代码
 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 }
View Code
复制代码

高精度加法

复制代码
 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 }
View Code
复制代码

高进度减法

复制代码
 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 }
View Code
复制代码

结构体排序

复制代码
 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 }
View Code
复制代码

进制转换

复制代码
 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 }
View Code
复制代码

拓扑排序

复制代码
 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 }
View Code
复制代码

图的深搜宽搜

复制代码
 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 }
View Code
复制代码

最短路 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 }
View Code
复制代码

最短路 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 }
View Code
复制代码

最短路 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 }
View Code
复制代码

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 }
View Code
复制代码

 快速幂

复制代码
 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 }
View Code
复制代码

 

posted @   超哥聊信奥  阅读(178)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示