| #define INF 0x3f3f3f |
| const int MAXN = 1000; |
| |
| * 欧拉函数 |
| * @param n 一个整数 |
| * @return 质因数个数 |
| */ |
| int eular(int n) { |
| int r = 1; |
| for (int i = 2; i * i <= n; ++i) { |
| if (n % i ==0) { |
| n /= i; |
| r *= i - 1; |
| while (n % i == 0) { |
| n /= i; |
| r *= i; |
| } |
| } |
| } |
| if (n > 1) r *= n - 1; |
| return r; |
| } |
| |
| * 约瑟夫问题 |
| * @param n 总人数 |
| * @param m 出队报数 |
| */ |
| void joseph(int n, int m) { |
| list<int> l; |
| for (int i = 1; i <= n; ++i) { |
| l.push_back(i); |
| } |
| auto it = l.begin(); |
| while (l.size() > 1) { |
| for (int j = 1; j < m; ++j) { |
| ++it; |
| if (it == l.end()) it = l.begin(); |
| } |
| it = l.erase(it); |
| if (it == l.end()) it = l.begin(); |
| } |
| cout << *it << endl; |
| } |
| |
| * 波兰表达式 |
| * @return 表达式结果 |
| */ |
| double poland() { |
| string s; |
| cin >> s; |
| switch (s[0]) { |
| case '+': return poland() + poland(); |
| case '-': return poland() - poland(); |
| case '*': return poland() * poland(); |
| case '/': return poland() / poland(); |
| default: return stod(s); |
| } |
| } |
| |
| int cnt = 0; |
| |
| * 汉诺塔算法 |
| * @param n 编号 |
| * @param x x 柱 |
| * @param y y 柱 |
| * @param z z 柱 |
| */ |
| void hanoi(int n, char x, char y, char z) { |
| if (n == 1) { |
| printf("%d %d %c=>%c\n", cnt++, n, x, z); |
| } |
| else { |
| hanoi(n - 1, x, z, y); |
| printf("%d %d %c=>%c\n", cnt++, n, x, z); |
| hanoi(n - 1, y, x, z); |
| } |
| } |
| struct Edge { |
| int from, to, cost; |
| Edge(int u, int v, int w) : from(u), to(v), cost(w) {} |
| bool operator< (const Edge& x) const { |
| return cost < x.cost; |
| } |
| }; |
| struct HeapNode { |
| int d, u; |
| bool operator< (const HeapNode& rhs) const { |
| return d > rhs.d; |
| } |
| HeapNode(int d, int u) : d(d), u(u) {} |
| }; |
| vector<Edge> edges; |
| vector<int> G[MAXN]; |
| |
| * for (int i = 0; i < E; ++i) { // E 是边数 |
| * int u, v, cost; |
| * cin >> u >> v >> cost; // 输入边的起点、终点和权值 |
| * G [u].push_back (i); // 存储边的索引 |
| * edges.push_back (Edge (u, v, cost)); |
| * G [v].push_back (i); // 存储边的索引 |
| * edges.push_back (Edge (v, u, cost)); |
| * } |
| */ |
| bool done[MAXN]; |
| int d[MAXN]; |
| |
| * Prim 算法 |
| * @param V 顶点数 |
| * @return 最小生成树长度 |
| */ |
| int Prim(int V) { |
| priority_queue<HeapNode> Q; |
| int ans = 0; |
| for (int i = 0; i < V; ++i) { |
| d[i] = INF; |
| } |
| d[0] = 0; |
| memset(done, 0, sizeof(done)); |
| Q.emplace(0, 0); |
| while (!Q.empty()) { |
| HeapNode x = Q.top(); |
| Q.pop(); |
| int u = x.u; |
| if (done[u]) continue; |
| ans += x.d; |
| done[u] = true; |
| for (int i : G[u]) { |
| Edge& e = edges[i]; |
| if (d[e.to] > e.cost) { |
| d[e.to] = e.cost; |
| Q.emplace(d[e.to], e.to); |
| } |
| } |
| } |
| return ans; |
| } |
| |
| * 并查集 |
| */ |
| class UnionFind{ |
| private: |
| vector<int> par; |
| public: |
| UnionFind(int V) { |
| for (int i = 0; i < V; ++i) { |
| par.emplace_back(i); |
| } |
| } |
| |
| * 查找根节点 |
| * @param x 待查节点 |
| * @return 根节点 |
| */ |
| int find(int x) { |
| if (par[x] == x) return x; |
| else return par[x] = find(par[x]); |
| } |
| |
| * 合并 |
| * @param x |
| * @param y |
| */ |
| void unite(int x, int y) { |
| x = find(x); |
| y = find(y); |
| if (x != y) { |
| par[x] = y; |
| } |
| } |
| |
| * 判断是否连通 |
| * @param x |
| * @param y |
| * @return 是否连通 |
| */ |
| bool same(int x, int y) { |
| return find(x) == find(y); |
| } |
| }; |
| |
| * Kruskal 算法 |
| * @param V 顶点数 |
| * @return 最小生成树长度 |
| */ |
| int Kruskal(int V) { |
| sort(edges.begin(), edges.end()); |
| UnionFind UF = UnionFind(V); |
| int ans = 0; |
| for (Edge e : edges) { |
| if (!UF.same(e.from, e.to)) { |
| UF.unite(e.from, e.to); |
| ans += e.cost; |
| } |
| } |
| return ans; |
| } |
| int path[MAXN]; |
| |
| * Dijkstra 算法 计算所有顶点到顶点 s 的最短路径 |
| * @param s 顶点 s |
| * @param V 顶点数 |
| */ |
| void Dijkstra(int s, int V) { |
| priority_queue<HeapNode> Q; |
| for (int i = 0; i < V; ++i) d[i] = INF; |
| d[s] = 0; |
| memset(done, 0 ,sizeof(done)); |
| Q.emplace(0, s); |
| while (!Q.empty()) { |
| HeapNode x = Q.top(); |
| Q.pop(); |
| int u = x.u; |
| if (done[u]) continue; |
| done[u] = true; |
| for (int i : G[u]) { |
| Edge& e = edges[i]; |
| if (d[e.to] > d[u] + e.cost) { |
| d[e.to] = d[u] + e.cost; |
| path[e.to] = i; |
| Q.emplace(d[e.to], e.to); |
| } |
| } |
| } |
| } |
| int dis[MAXN][MAXN]; |
| int p[MAXN][MAXN]; |
| |
| * FloydWarshall 算法 计算全源最短路径 |
| * @param V 顶点数 |
| */ |
| void FloydWarshall(int V) { |
| |
| for (int i = 0; i < V; ++i) { |
| for (int j = 0; j < V; ++j) { |
| if (i == j) dis[i][j] = 0; |
| else dis[i][j] = INF; |
| p[i][j] = -1; |
| } |
| } |
| |
| for (Edge e : edges) { |
| if (dis[e.from][e.to] > e.cost) { |
| dis[e.from][e.to] = e.cost; |
| p[e.from][e.to] = e.from; |
| } |
| } |
| |
| for (int k = 0; k < V; ++k) { |
| for (int i = 0; i < V; ++i) { |
| for (int j = 0; j < V; ++j) { |
| if (dis[i][k] != INF && dis[k][j] != INF && dis[i][j] > dis[i][k] + dis[k][j]) { |
| dis[i][j] = dis[i][k] + dis[k][j]; |
| p[i][j] = p[k][j]; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| * 拓扑排序 |
| * @param V |
| * @return 拓扑序列 |
| */ |
| vector<int> TopologicalSort(int V) { |
| int inDegree[MAXN]; |
| vector<int> result; |
| queue<int> Q; |
| for (Edge e : edges) { |
| inDegree[e.to]++; |
| } |
| for (int i = 0; i < V; ++i) { |
| if (inDegree[i] == 0) Q.emplace(i); |
| } |
| while (!Q.empty()) { |
| int u = Q.front(); |
| Q.pop(); |
| result.emplace_back(u); |
| for (int i : G[u]) { |
| Edge& e = edges[i]; |
| int v = e.to; |
| if (--inDegree[v] == 0) { |
| Q.emplace(v); |
| } |
| } |
| } |
| } |
| |
| * 小根堆 |
| */ |
| class MinHeap { |
| private: |
| vector<int> a; |
| public: |
| |
| * 调整堆 |
| * @param i 传入节点下标 |
| */ |
| void adjustHeap(int i) { |
| int n = a.size(); |
| int lChild = i * 2 + 1; |
| int rChild = i * 2 + 2; |
| int minI = i; |
| if (lChild < n && a[lChild] < a[minI]) { |
| minI = lChild; |
| } |
| if (rChild < n && a[rChild] < a[minI]) { |
| minI = rChild; |
| } |
| if (minI != i) { |
| swap(a[minI], a[i]); |
| adjustHeap(minI); |
| } |
| } |
| |
| * 构造函数 |
| * @param b 原始数组 |
| */ |
| MinHeap(const vector<int>& b) { |
| a = b; |
| int n = b.size(); |
| for (int i = n / 2 - 1; i >= 0; --i) { |
| adjustHeap(i); |
| } |
| } |
| }; |