模版代码总结
树的重心:
1 #include <cstdio> 2 #include <algorithm> 3 4 const int MAXN = 1e5; 5 const int INF = 0x3f3f3f3f; 6 7 int n; 8 int head[2 * MAXN + 10], numEdge; 9 int size[2 * MAXN + 10], maxp, pos; 10 11 struct Edge { 12 int nxt, to; 13 }edge[2 * MAXN + 10]; 14 15 void addEdge(int x, int y) { 16 17 ++numEdge; 18 edge[numEdge].nxt = head[x]; 19 edge[numEdge].to = y; 20 head[x] = numEdge; 21 22 return; 23 } 24 25 void dfs(int u, int father) { 26 27 int maxPart = -1; 28 size[u] = 1; 29 for(int i = head[u]; i; i = edge[i].nxt) { 30 int k = edge[i].to; 31 if(k != father) { 32 dfs(k, u); 33 size[u] += size[k]; 34 maxPart = std::max(maxPart, size[k]); 35 } 36 } 37 maxPart = std::max(maxPart, n - size[u]); 38 39 if(maxPart < maxp) { 40 maxp = maxPart; 41 pos = u; 42 } 43 44 return; 45 } 46 47 int main() { 48 49 scanf("%d", &n); 50 for(int i = 1; i <= n - 1; ++i) { 51 int x, y; 52 scanf("%d %d", &x, &y); 53 addEdge(x, y); 54 addEdge(y, x); 55 } 56 57 maxp = INF; 58 dfs(1, -1); 59 60 printf("%d\n", pos); 61 62 return 0; 63 }
树的直径:
1 #include <cstdio> 2 #include <algorithm> 3 4 const int MAXN = 1e5; 5 6 int n; 7 int head[2 * MAXN + 10], numEdge; 8 int SmaxDis[2 * MAXN + 10], PmaxDis[2 * MAXN + 10]; 9 10 struct Edge { 11 int nxt, to, val; 12 }edge[2 * MAXN + 10]; 13 14 void addEdge(int x, int y, int val) { 15 16 ++numEdge; 17 edge[numEdge].nxt = head[x]; 18 edge[numEdge].to = y; 19 edge[numEdge].val = val; 20 head[x] = numEdge; 21 22 return; 23 } 24 25 void dfs(int u, int father) { 26 27 for(int i = head[u]; i; i = edge[i].nxt) { 28 int k = edge[i].to; 29 if(k != father) { 30 dfs(k, u); 31 SmaxDis[u] = std::max(SmaxDis[u], SmaxDis[k] + edge[i].val); 32 } 33 } 34 35 return; 36 } 37 38 void dp(int u, int father) { 39 40 int t = 0; 41 for(int i = head[u]; i; i = edge[i].nxt) { 42 int k = edge[i].to; 43 if(k != father) { 44 dp(k, u); 45 PmaxDis[u] = std::max(PmaxDis[u], t + SmaxDis[k] + edge[i].val); 46 t = std::max(t, SmaxDis[k] + edge[i].val); 47 } 48 } 49 50 return; 51 } 52 53 int main() { 54 55 scanf("%d", &n); 56 for(int i = 1; i <= n - 1; ++i) { 57 int x, y, val; 58 scanf("%d %d %d", &x, &y, &val); 59 addEdge(x, y, val); 60 addEdge(y, x, val); 61 } 62 63 dfs(1, -1); 64 dp(1, -1); 65 66 int ans = -1; 67 for(int i = 1; i <= n; ++i) { 68 ans = std::max(ans, PmaxDis[i]); 69 } 70 printf("%d\n", ans); 71 72 return 0; 73 }
Dijkstra:
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 6 const int MAXN = 1000; 7 const int MAXM = 1000; 8 const int INF = 0x3f3f3f3f; 9 10 int n, m, s; 11 int head[2 * MAXN + 10], numEdge; 12 int dis[2 * MAXN + 10]; 13 bool vis[2 * MAXN + 10]; 14 15 struct Edge { 16 int nxt, to, val; 17 }edge[2 * MAXM + 10]; 18 19 void add_Edge(int x, int t, int val) { 20 21 ++numEdge; 22 edge[numEdge].nxt = head[x]; 23 edge[numEdge].to = t; 24 edge[numEdge].val = val; 25 head[x] = numEdge; 26 27 return; 28 } 29 30 void dijkstra() { 31 32 std::memset(dis, 0x3f, sizeof(dis)); 33 std::memset(vis, false, sizeof(vis)); 34 dis[s] = 0; 35 36 for(int k = 1; k <= n; ++k) { 37 int cur; 38 int minDis = INF; 39 for(int i = 1; i <= n; ++i) { 40 if(dis[i] < minDis && !vis[i]) { 41 minDis = dis[i]; 42 cur = i; 43 } 44 } 45 vis[cur] = true; 46 for(int i = head[cur]; i; i = edge[i].nxt) { 47 int t = edge[i].to; 48 dis[t] = std::min(dis[t], dis[cur] + edge[i].val); 49 } 50 } 51 52 return; 53 } 54 55 int main() { 56 57 scanf("%d %d %d", &n, &m, &s); 58 for(int i = 1; i <= m; ++i) { 59 int x, t, val; 60 scanf("%d %d %d", &x, &t, &val); 61 add_Edge(x, t, val); 62 } 63 64 dijkstra(); 65 66 for(int i = 1; i <= n; ++i) { 67 printf("%d ", dis[i]); 68 } 69 70 return 0; 71 }
Dijkstra + 堆优化:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 5 using std::pair; 6 using std::make_pair; 7 8 const int MAXN = 100000; 9 const int MAXM = 200000; 10 11 int n, m, s; 12 int head[2 * MAXN + 10], numEdge; 13 int dis[2 * MAXN + 10]; 14 bool vis[2 * MAXN + 10]; 15 16 std::priority_queue<pair<int, int>, std::vector<pair<int, int> >, std::greater<pair<int, int> > >heap; 17 18 struct Edge { 19 int nxt, to, val; 20 }edge[2 * MAXM + 10]; 21 22 void addEdge(int x, int t, int val) { 23 24 ++numEdge; 25 edge[numEdge].nxt = head[x]; 26 edge[numEdge].to = t; 27 edge[numEdge].val = val; 28 head[x] = numEdge; 29 30 return; 31 } 32 33 void dijkstra() { 34 35 std::memset(dis, 0x3f, sizeof(dis)); 36 std::memset(vis, false, sizeof(vis)); 37 dis[s] = 0; 38 heap.push(make_pair(dis[s], s)); 39 40 while(!heap.empty()) { 41 int cur = heap.top().second; 42 heap.pop(); 43 if(!vis[cur]) { 44 vis[cur] = true; 45 for(int i = head[cur]; i; i = edge[i].nxt) { 46 int t = edge[i].to; 47 if(dis[t] > dis[cur] + edge[i].val) { 48 dis[t] = dis[cur] + edge[i].val; 49 heap.push(make_pair(dis[t], t)); 50 } 51 } 52 } 53 } 54 55 return; 56 } 57 58 int main() { 59 60 scanf("%d %d %d", &n, &m, &s); 61 for(int i = 1; i <= m; ++i) { 62 int x, t, val; 63 scanf("%d %d %d", &x, &t, &val); 64 addEdge(x, t, val); 65 } 66 67 dijkstra(); 68 69 for(int i = 1; i <= n; ++i) { 70 printf("%d ", dis[i]); 71 } 72 73 return 0; 74 }
Floyd:
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 const int MAXN = 100; 6 const int INF = 0x3f3f3f3f; 7 8 int n, m, s; 9 int dis[2 * MAXN + 10][2 * MAXN + 10]; 10 11 void floyd() { 12 13 dis[s][s] = 0; 14 for(int k = 1; k <= n; ++k) { 15 for(int i = 1; i <= n; ++i) { 16 if(k == i || dis[i][k] == INF) { 17 continue; 18 } 19 for(int j = 1; j <= n; ++j) { 20 dis[i][j] = std::min(dis[i][j], dis[i][k] + dis[k][j]); 21 } 22 } 23 } 24 25 return; 26 } 27 28 int main() { 29 30 scanf("%d %d %d", &n, &m, &s); 31 memset(dis, 0x3f, sizeof(dis)); 32 for(int i = 1; i <= m; ++i) { 33 int x, t, val; 34 scanf("%d %d %d", &x, &t, &val); 35 dis[x][t] = std::min(dis[x][t], val); 36 } 37 38 floyd(); 39 40 for(int i = 1; i <= n; ++i) { 41 printf("%d ", dis[s][i] != INF ? dis[s][i] : 2147483647); 42 } 43 44 return 0; 45 }
SPFA:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 5 const int MAXN = 10000; 6 const int MAXM = 500000; 7 const int INF = 0x3f3f3f3f; 8 9 int n, m, s; 10 int head[2 * MAXN + 10], numEdge; 11 int dis[2 * MAXN + 10]; 12 bool vis[2 * MAXN + 10]; 13 14 std::queue<int>que; 15 16 struct Edge { 17 int nxt, to, val; 18 }edge[2 * MAXM + 10]; 19 20 void addEdge(int x, int t, int val) { 21 22 ++numEdge; 23 edge[numEdge].nxt = head[x]; 24 edge[numEdge].to = t; 25 edge[numEdge].val = val; 26 head[x] = numEdge; 27 28 return; 29 } 30 31 void spfa() { 32 33 std::memset(dis, 0x3f, sizeof(dis)); 34 std::memset(vis, false, sizeof(vis)); 35 dis[s] = 0; 36 vis[s] = true; 37 que.push(s); 38 39 while(!que.empty()) { 40 int cur = que.front(); 41 que.pop(); 42 vis[cur] = false; 43 for(int i = head[cur]; i; i = edge[i].nxt) { 44 int t = edge[i].to; 45 if(dis[t] > dis[cur] + edge[i].val) { 46 dis[t] = dis[cur] + edge[i].val; 47 if(!vis[t]) { 48 vis[t] = true; 49 que.push(t); 50 } 51 } 52 } 53 } 54 55 return; 56 } 57 58 int main() { 59 60 scanf("%d %d %d", &n, &m, &s); 61 for(int i = 1; i <= m; ++i) { 62 int x, t, val; 63 scanf("%d %d %d", &x, &t, &val); 64 addEdge(x, t, val); 65 } 66 67 spfa(); 68 69 for(int i = 1; i <= n; ++i) { 70 printf("%d ", dis[i] != INF ? dis[i] : 2147483647); 71 } 72 73 return 0; 74 }
Kruskal:
1 #include <cstdio> 2 #include <algorithm> 3 4 const int MAXN = 5000; 5 const int MAXM = 200000; 6 7 int n, m; 8 int fa[2 * MAXN + 10]; 9 int ans; 10 bool flag; 11 12 struct Edge { 13 int x, y, val; 14 }edge[2 * MAXM + 10]; 15 16 int find(int x) { 17 return fa[x] == x ? x : fa[x] = find(fa[x]); 18 } 19 20 void unity(int x, int y) { 21 fa[find(x)] = find(y); 22 } 23 24 bool cmp(Edge a, Edge b) { 25 return a.val < b.val; 26 } 27 28 void kruskal() { 29 30 int cnt = 0; 31 flag = false; 32 std::sort(edge + 1, edge + m + 1, cmp); 33 for(int i = 1; i <= n; ++i) { 34 fa[i] = i; 35 } 36 37 for(int i = 1; i <= m; ++i) { 38 int x = edge[i].x; 39 int y = edge[i].y; 40 if(find(x) != find(y)) { 41 unity(x, y); 42 ans += edge[i].val; 43 ++cnt; 44 if(cnt == n - 1) { 45 flag = true; 46 break; 47 } 48 } 49 } 50 51 return; 52 } 53 54 int main() { 55 56 scanf("%d %d", &n, &m); 57 for(int i = 1; i <= m; ++i) { 58 scanf("%d %d %d", &edge[i].x, &edge[i].y, &edge[i].val); 59 } 60 61 kruskal(); 62 63 if(flag) { 64 printf("%d\n", ans); 65 } 66 else { 67 puts("orz"); 68 } 69 70 return 0; 71 }
Prim:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int MAXN = 5000; 6 const int MAXM = 200000; 7 const int INF = 0x3f3f3f3f; 8 9 int n, m; 10 int head[2 * MAXN + 10], numEdge; 11 int disT[2 * MAXN + 10], vis[2 * MAXN + 10]; 12 int ans; 13 bool flag; 14 15 struct Edge { 16 int nxt, to, val; 17 }edge[2 * MAXM + 10]; 18 19 void addEdge(int x, int t, int val) { 20 21 ++numEdge; 22 edge[numEdge].nxt = head[x]; 23 edge[numEdge].to = t; 24 edge[numEdge].val = val; 25 head[x] = numEdge; 26 27 return; 28 } 29 30 void prim() { 31 32 std::memset(disT, 0x3f, sizeof(disT)); 33 std::memset(vis, false, sizeof(vis)); 34 disT[1] = 0; 35 flag = true; 36 37 for(int k = 1; k <= n; ++k) { 38 int cur = 0; 39 int minDis = INF; 40 for(int i = 1; i <= n; ++i) { 41 if(!vis[i] && disT[i] < minDis) { 42 minDis = disT[i]; 43 cur = i; 44 } 45 } 46 if(!cur) { 47 flag = false; 48 break; 49 } 50 ans += disT[cur]; 51 disT[cur] = 0; 52 vis[cur] = true; 53 for(int i = head[cur]; i; i = edge[i].nxt) { 54 int t = edge[i].to; 55 if(!vis[t]) { 56 disT[t] = std::min(disT[t], edge[i].val); 57 } 58 } 59 } 60 61 return; 62 } 63 64 int main() { 65 66 scanf("%d %d", &n, &m); 67 for(int i = 1; i <= m; ++i) { 68 int x, y, val; 69 scanf("%d %d %d", &x, &y, &val); 70 addEdge(x, y, val); 71 addEdge(y, x, val); 72 } 73 74 prim(); 75 76 if(!flag) { 77 puts("orz"); 78 } 79 else { 80 printf("%d\n", ans); 81 } 82 83 return 0; 84 }
LCA(St表做法):
1 #include <cstdio> 2 #include <algorithm> 3 4 const int MAXN = 5e5; 5 6 int n, m, s; 7 int head[2 * MAXN + 10], numEdge; 8 int id[2 * MAXN + 10], depth[2 * MAXN + 10], app[2 * MAXN + 10], cnt; 9 int lg2[2 * MAXN + 10]; 10 11 struct Edge { 12 int nxt, to; 13 }edge[2 * MAXN + 10]; 14 15 struct St { 16 int depth, id; 17 }Min[2 * MAXN + 10][32]; 18 19 void addEdge(int x, int y) { 20 21 ++numEdge; 22 edge[numEdge].nxt = head[x]; 23 edge[numEdge].to = y; 24 head[x] = numEdge; 25 26 return; 27 } 28 29 void dfs(int u, int father) { 30 31 ++cnt; 32 depth[u] = depth[father] + 1; 33 id[cnt] = u; 34 app[u] = cnt; 35 36 for(int i = head[u]; i; i = edge[i].nxt) { 37 int k = edge[i].to; 38 if(k != father) { 39 dfs(k, u); 40 id[++cnt] = u; 41 } 42 } 43 44 return; 45 } 46 47 St MIN(St a, St b) { 48 return a.depth < b.depth ? a : b; 49 } 50 51 void st() { 52 53 for(int i = 1; i <= cnt; ++i) { 54 Min[i][0] = (St){depth[id[i]], id[i]}; 55 } 56 57 for(int k = 1; (1 << k) <= cnt; ++k) { 58 for(int i = 1; i + (1 << k) - 1 <= cnt; ++i) { 59 Min[i][k] = MIN(Min[i][k - 1], Min[i + (1 << (k - 1))][k - 1]); 60 } 61 } 62 63 return; 64 } 65 66 int query(int l, int r) { 67 if(l > r) std::swap(l, r); 68 int k = lg2[r - l + 1]; 69 return MIN(Min[l][k], Min[r - (1 << k) + 1][k]).id; 70 } 71 72 int main() { 73 74 scanf("%d %d %d", &n, &m, &s); 75 for(int i = 1; i <= n - 1; ++i) { 76 int x, y; 77 scanf("%d %d", &x, &y); 78 addEdge(x, y); 79 addEdge(y, x); 80 } 81 82 dfs(s, -1); 83 st(); 84 85 lg2[1] = 0; 86 for(int i = 2; i <= cnt; ++i) { 87 lg2[i] = lg2[i / 2] + 1; 88 } 89 90 for(int i = 1; i <= m; ++i) { 91 int a, b; 92 scanf("%d %d", &a, &b); 93 printf("%d\n", query(app[a], app[b])); 94 } 95 96 return 0; 97 }
树状数组:
1 #include <cstdio> 2 3 const int MAXN = 5e5; 4 5 int n, m; 6 int bit[2 * MAXN + 10]; 7 8 int lowbit(int x) { 9 return x & -x; 10 } 11 12 void add(int x, int k) { 13 for(; x <= n; x += lowbit(x)) { 14 bit[x] += k; 15 } 16 return; 17 } 18 19 int query(int x) { 20 int ans = 0; 21 for(; x >= 1; x -= lowbit(x)) { 22 ans += bit[x]; 23 } 24 return ans; 25 } 26 27 int main() { 28 29 scanf("%d %d", &n, &m); 30 for(int i = 1; i <= n; ++i) { 31 int x; 32 scanf("%d", &x); 33 add(i, x); 34 } 35 36 for(int i = 1; i <= m; ++i) { 37 int op; 38 scanf("%d", &op); 39 if(op == 1) { 40 int x, k; 41 scanf("%d %d", &x, &k); 42 add(x, k); 43 } 44 else if(op == 2) { 45 int x, y; 46 scanf("%d %d", &x, &y); 47 printf("%d\n", query(y) - query(x - 1)); 48 } 49 } 50 51 return 0; 52 }
并查集:
1 #include <cstdio> 2 3 const int MAXN = 1e3; 4 5 int n, m; 6 int fa[2 * MAXN + 10]; 7 8 int find(int x) { 9 return x == fa[x] ? x : fa[x] = find(fa[x]); 10 } 11 12 void unity(int x, int y) { 13 fa[find(x)] = find(y); 14 } 15 16 int main() { 17 18 while(true) { 19 20 scanf("%d", &n); 21 if(n == 0) break; 22 for(int i = 1; i <= n; ++i) { 23 fa[i] = i; 24 } 25 26 scanf("%d", &m); 27 for(int i = 1; i <= m; ++i) { 28 int x, y; 29 scanf("%d %d", &x, &y); 30 unity(x, y); 31 } 32 33 int ans = -1; 34 for(int i = 1; i <= n; ++i) { 35 if(find(i) == i) { 36 ++ans; 37 } 38 } 39 40 printf("%d\n", ans); 41 } 42 43 return 0; 44 }
St表:
1 #include <cstdio> 2 #include <algorithm> 3 4 const int MAXN = 1e5; 5 6 int n, m; 7 int Max[2 * MAXN + 10][32]; 8 int lg2[2 * MAXN + 10]; 9 10 void st() { 11 12 for(int k = 1; (1 << k) <= n; ++k) { 13 for(int i = 1; i + (1 << k) - 1 <= n; ++i) { 14 Max[i][k] = std::max(Max[i][k - 1], Max[i + (1 << (k - 1))][k - 1]); 15 } 16 } 17 18 return; 19 } 20 21 int query(int l, int r) { 22 int k = lg2[r - l + 1]; 23 return std::max(Max[l][k], Max[r - (1 << k) + 1][k]); 24 } 25 26 int main() { 27 28 scanf("%d %d", &n, &m); 29 for(int i = 1; i <= n; ++i) { 30 scanf("%d", &Max[i][0]); 31 } 32 33 st(); 34 35 lg2[1] = 0; 36 for(int i = 2; i <= n; ++i) { 37 lg2[i] = lg2[i / 2] + 1; 38 } 39 40 for(int i = 1; i <= m; ++i) { 41 int l, r; 42 scanf("%d %d", &l, &r); 43 printf("%d\n", query(l, r)); 44 } 45 46 return 0; 47 }