├── README.md ├── STL笔记.pdf ├── 刷题笔记.pdf ├── 模板代码 ├── KMP.cpp ├── binaryGraphMatching.cpp ├── dijkstra.cpp ├── disjointSet.cpp ├── maxFlow.cpp ├── readWrite.cpp ├── spfa.cpp ├── tmp.cpp └── treeArray.cpp ├── 笔记.pdf ├── 经典算法笔记.pdf └── 背包九讲.pdf /README.md: -------------------------------------------------------------------------------- 1 | # 【刷题】保研机试题型分类 2 | 3 | 更新,如果你是OI大佬,ACM大佬,那这份题型分类对你来说可能太简单了,仅供参考。在我看来,这个分类似乎更适合像我一样的算法题0基础的同学从0开始学习的难度。 4 | 5 | ----------------------------------------- 6 | 7 | 这里是我在1月到7月刷的一些有分类的题型的总结。博主的保研之路已经圆满结束,成功拿到了本校的offer。虽然因为疫情原因,博主参加的夏令营基本都取消了机考,但面试的时候还是受益于做过的这些题,因此分享出来,大家也可以参考一下。其中[笔记.pdf](https://github.com/EricLee8/BaoYan-Algorithm-Problems/blob/master/笔记.pdf)是这些题我写的一些题解和易错点,不过太过随意,大家最好在网上搜题解。[刷题笔记.pdf](https://github.com/EricLee8/BaoYan-Algorithm-Problems/blob/master/刷题笔记.pdf)里还有一些题目。[经典算法笔记.pdf](https://github.com/EricLee8/BaoYan-Algorithm-Problems/blob/master/经典算法笔记.pdf)记录了一些经典的算法,其代码在[模板代码](https://github.com/EricLee8/BaoYan-Algorithm-Problems/blob/master/模板代码/)里可以找到。[STL笔记.pdf](https://github.com/EricLee8/BaoYan-Algorithm-Problems/blob/master/STL笔记.pdf)记录了一些STL的常用数据结构。 8 | 9 | ## 枚举法 10 | 11 | - 假硬币:[http://noi.openjudge.cn/ch0201/15/](http://noi.openjudge.cn/ch0201/15/) 12 | - 五户共井问题:[http://noi.openjudge.cn/ch0201/7623/](http://noi.openjudge.cn/ch0201/7623/) 13 | - 画家问题:[http://noi.openjudge.cn/ch0201/1815/](http://noi.openjudge.cn/ch0201/1815/) 14 | - 因子问题:[http://noi.openjudge.cn/ch0201/2723/](http://noi.openjudge.cn/ch0201/2723/) 15 | - 我家的门牌号:[http://noi.openjudge.cn/ch0201/7649/](http://noi.openjudge.cn/ch0201/7649/) 16 | 17 | ## 递归和递推 18 | - PKU2506Tiling(递推):[http://noi.openjudge.cn/ch0202/9273/](http://noi.openjudge.cn/ch0202/9273/) 19 | - 放苹果(递推):[http://noi.openjudge.cn/ch0202/666/](http://noi.openjudge.cn/ch0202/666/) 20 | - 二叉树问题:[http://t.cn/Ai0Ke6I0](http://t.cn/Ai0Ke6I0) 21 | - 2的幂次方表示(上交复试题):[http://noi.openjudge.cn/ch0202/8758/](http://noi.openjudge.cn/ch0202/8758/) 22 | 23 | ## 分治 24 | 25 | - 求排列的逆序数(O(nlogn)):[http://noi.openjudge.cn/ch0204/7622/](http://noi.openjudge.cn/ch0204/7622/) 26 | - 2011:[http://noi.openjudge.cn/ch0204/2991/](http://noi.openjudge.cn/ch0204/2991/) 27 | - 找第k大的数(快排思想) 28 | 29 | ## 搜索 30 | ### 广度优先BFS 31 | - Catch That Cow:[http://acm.hdu.edu.cn/showproblem.php?pid=2717](http://acm.hdu.edu.cn/showproblem.php?pid=2717) 32 | - Find The Multiple:[http://poj.org/problem?id=1426](http://poj.org/problem?id=1426) 33 | - 玛雅人的密码(清华复试):[http://t.cn/Ai0lUhJj](http://t.cn/Ai0lUhJj) 34 | ### 深度优先DFS 35 | - 神奇的口袋(北大复试,这题dp也能做,其实就是subset sum):[http://t.cn/Ai0u0GUz](http://t.cn/Ai0u0GUz) 36 | - 碎纸机:[http://noi.openjudge.cn/ch0205/1805/](http://noi.openjudge.cn/ch0205/1805/) 37 | ### 不告诉你广搜还是深搜ww 38 | - 鸣人和佐助(带限制的最短路):[http://noi.openjudge.cn/ch0205/6044/](http://noi.openjudge.cn/ch0205/6044/) 39 | - 无线网络:[http://118.190.20.162/view.page?gpid=T7](http://118.190.20.162/view.page?gpid=T7) 40 | - 算24:[http://noi.openjudge.cn/ch0205/1789/](http://noi.openjudge.cn/ch0205/1789/) 41 | - 寻找Nemo:[http://noi.openjudge.cn/ch0205/1998/](http://noi.openjudge.cn/ch0205/1998/) 42 | - 取石子游戏(感觉这题不太像搜索,其实就是博弈论的一种):[http://noi.openjudge.cn/ch0205/6266/](http://noi.openjudge.cn/ch0205/6266/) 43 | ## 字符串 44 | - Oulipo(KMP板子题,KMP一定要掌握):[http://acm.hdu.edu.cn/showproblem.php?pid=1686](http://acm.hdu.edu.cn/showproblem.php?pid=1686) 45 | ## 线性数据结构 46 | - Powerful Calculator(栈):[https://www.nowcoder.com/practice/6bc1dd2ee0ce4257821531719b8d1c83](https://www.nowcoder.com/practice/6bc1dd2ee0ce4257821531719b8d1c83) 47 | - Blah数集(队列):[http://noi.openjudge.cn/ch0304/2729/](http://noi.openjudge.cn/ch0304/2729/) 48 | ## 数学问题 49 | ### 进制转换 50 | 略,但是要会任意m进制转n进制的方法 51 | ### 质数相关 52 | - 整除问题(上交复试):[https://www.nowcoder.com/practice/8e29045de1c84d349b43fdb123ab586a](https://www.nowcoder.com/practice/8e29045de1c84d349b43fdb123ab586a) 53 | ### 快速幂、高精度 54 | 略,快速幂模板要记一下,高精度最好也记一下以防万一。 55 | 56 | ## 非线性数据结构 57 | 58 | - 特殊的前序建树:[http://t.cn/AiKuUtlX](http://t.cn/AiKuUtlX) 59 | - 已知前中遍历序列建树:[http://t.cn/AiKgDfLU](http://t.cn/AiKgDfLU) 60 | - 哈弗曼树权重计算:[http://t.cn/AiCuGMki](http://t.cn/AiCuGMki) 61 | 62 | ## 贪心 63 | - To fill or not to fill:[https://www.nowcoder.com/practice/f7eba38f7cd24c45982831e0f38518f9](https://www.nowcoder.com/practice/f7eba38f7cd24c45982831e0f38518f9) 64 | - 最短前缀:[http://noi.openjudge.cn/ch0406/1799](http://noi.openjudge.cn/ch0406/1799) 65 | - 电池的寿命:[http://noi.openjudge.cn/ch0406/2469/](http://noi.openjudge.cn/ch0406/2469/) 66 | - Magic of David Copperfield:[http://noi.openjudge.cn/ch0406/712/](http://noi.openjudge.cn/ch0406/712/) 67 | - 拼点游戏(难):[http://noi.openjudge.cn/ch0406/2986/](http://noi.openjudge.cn/ch0406/2986/) 68 | - 特殊密码锁(感觉不太像贪心?):[http://noi.openjudge.cn/ch0406/8469/](http://noi.openjudge.cn/ch0406/8469/) 69 | - Cell Phone Network(连通图最小支配集板子题):[http://noi.openjudge.cn/ch0406/2384/](http://noi.openjudge.cn/ch0406/2384/) 70 | - Ride to Office:[http://noi.openjudge.cn/ch0406/2404/](http://noi.openjudge.cn/ch0406/2404/) 71 | 72 | ## 图算法 73 | - 宗教信仰(连通分支计算):[http://noi.openjudge.cn/ch0403/1526/](http://noi.openjudge.cn/ch0403/1526/) 74 | - 丛林中的路(并查集):[http://noi.openjudge.cn/ch0403/253/](http://noi.openjudge.cn/ch0403/253/) 75 | - Gopher II(二部图匹配):[http://noi.openjudge.cn/ch0403/1538/](http://noi.openjudge.cn/ch0403/1538/) 76 | - ROADS(带限制的最短路):[http://noi.openjudge.cn/ch0403/726/](http://noi.openjudge.cn/ch0403/726/) 77 | - Is It A Tree(有向树的判定):[http://noi.openjudge.cn/ch0308/310/](http://noi.openjudge.cn/ch0308/310/) 78 | - Professor John(Floyd算法传递闭包):[http://noi.openjudge.cn/ch0308/3529/](http://noi.openjudge.cn/ch0308/3529/) 79 | - 最短路径问题(二重最短路):[http://t.cn/AilPbME2](http://t.cn/AilPbME2) 80 | - Legal or Not(拓扑排序):[http://acm.hdu.edu.cn/showproblem.php?pid=3342](http://acm.hdu.edu.cn/showproblem.php?pid=3342) 81 | - Instruction Arrangement(关键路径,即AOE问题):[http://acm.hdu.edu.cn/showproblem.php?pid=4109](http://acm.hdu.edu.cn/showproblem.php?pid=4109) 82 | - 畅通工程:[http://t.cn/AiOvBHj9](http://t.cn/AiOvBHj9) 83 | - 找出直系亲属:[http://t.cn/AiOzQMBH](http://t.cn/AiOzQMBH) 84 | - 最短路径(上交复试):[https://www.nowcoder.com/practice/a29d0b5eb46b4b90bfa22aa98cf5ff17](https://www.nowcoder.com/practice/a29d0b5eb46b4b90bfa22aa98cf5ff17) 85 | - 确定比赛名次:[http://acm.hdu.edu.cn/showproblem.php?pid=1285](http://acm.hdu.edu.cn/showproblem.php?pid=1285) 86 | 87 | ## 动态规划 88 | 最大连续子段和、最大公共子序列(LCS)、最大递增子序列(LIS)和背包问题等一定要先烂熟于胸(背包问题可以看《背包九讲》)。特别是各种背包问题,保研机试考的dp大部分都是背包问题的变种。 89 | 90 | - 合唱队形:[http://t.cn/AiYNyHPe](http://t.cn/AiYNyHPe) 91 | - 最小邮票数:[http://t.cn/AiYlwchD](http://t.cn/AiYlwchD) 92 | - 买书:[http://noi.openjudge.cn/ch0206/6049/](http://noi.openjudge.cn/ch0206/6049/) 93 | - 宠物小精灵之收服:[http://noi.openjudge.cn/ch0206/4978/](http://noi.openjudge.cn/ch0206/4978/) 94 | - 鸣人的影分身:[http://noi.openjudge.cn/ch0206/8467/](http://noi.openjudge.cn/ch0206/8467/) 95 | - 切割回文:[http://noi.openjudge.cn/ch0206/8471/](http://noi.openjudge.cn/ch0206/8471/) 96 | - 奶牛散步:[http://noi.openjudge.cn/ch0206/9271/](http://noi.openjudge.cn/ch0206/9271/) 97 | - 鸡蛋的硬度:[http://noi.openjudge.cn/ch0206/7627/](http://noi.openjudge.cn/ch0206/7627/) 98 | - 摘花生:[http://noi.openjudge.cn/ch0206/2728/](http://noi.openjudge.cn/ch0206/2728/) 99 | - 方格取数(多线程dp):[http://noi.openjudge.cn/ch0206/8786/](http://noi.openjudge.cn/ch0206/8786/) 100 | - 酒鬼:[http://noi.openjudge.cn/ch0206/9268/](http://noi.openjudge.cn/ch0206/9268/) 101 | - 计算字符串距离(edit distance裸题):[http://noi.openjudge.cn/ch0206/2988/](http://noi.openjudge.cn/ch0206/2988/) 102 | - 海贼王之伟大航路(状压dp,感觉机试应该不会考这种):[http://noi.openjudge.cn/ch0405/4979/](http://noi.openjudge.cn/ch0405/4979/) 103 | - 完美覆盖:[http://noi.openjudge.cn/ch0405/1665/](http://noi.openjudge.cn/ch0405/1665/) 104 | - 雷涛的小猫:[http://noi.openjudge.cn/ch0405/2454/](http://noi.openjudge.cn/ch0405/2454/) 105 | - 偶数个数字3:[http://noi.openjudge.cn/ch0206/9272/](http://noi.openjudge.cn/ch0206/9272/) 106 | -------------------------------------------------------------------------------- /STL笔记.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLee8/BaoYan-Algorithm-Problems/c321f9b5da631cd53594a6f040bb745e4fe1af66/STL笔记.pdf -------------------------------------------------------------------------------- /刷题笔记.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricLee8/BaoYan-Algorithm-Problems/c321f9b5da631cd53594a6f040bb745e4fe1af66/刷题笔记.pdf -------------------------------------------------------------------------------- /模板代码/KMP.cpp: -------------------------------------------------------------------------------- 1 | int KMP(string text, string pattern) 2 | { 3 | int i, j, m = pattern.size(), n = text.size(); 4 | int* nxt = new int [m]; 5 | nxt[0] = -1; // nxt[i]表示i这个位置前后缀相等的最大前缀的最后一个字符的下标哈 6 | for(int i=1; i=0 && pattern[nxt[j]+1]!=pattern[i]) j = nxt[j]; //如果不相等就一直往nxt[j]找下去直到相等或者j<0 10 | if(j<0) nxt[i] = -1; 11 | else nxt[i] = nxt[j]+1; //刚刚相等的那个地方 12 | } 13 | 14 | i = j = 0; //开始从头匹配 15 | while(i=0 && pattern[nxt[j]+1]!=pattern[i]) j = nxt[j]; 36 | if(j<0) nxt[i] = -1; 37 | else nxt[i] = nxt[j] + 1; 38 | } 39 | i = j = 0; 40 | while(i=0 && pattern[nxt[j]+1]!=pattern[i]) j = nxt[j]; 61 | if(j<0) nxt[i] = -1; 62 | else nxt[i] = nxt[j]+1; 63 | } 64 | i = j = 0; 65 | while(i=0 && pattern[nxt[j]+1]!=pattern[i]) j = nxt[j]; 87 | if(j<0) nxt[i] = -1; 88 | else nxt[i] = nxt[j] + 1; 89 | } 90 | // ========================= 多重匹配 =========================== 91 | i = j = 0; 92 | while(i=0 && pattern[nxt[j]+1]!=pattern[i]) j = nxt[j]; 116 | if(j<0) nxt[i] = -1; 117 | else nxt[i] = nxt[j]+1; 118 | } 119 | //默写一下多重匹配的 120 | i = j =0; 121 | int num = 0; 122 | while(i 2 | 3 | int m, n, start; 4 | const int MAXN = 205; 5 | bool vis[MAXN]; 6 | int dis[MAXN]; 7 | 8 | class node{ 9 | public: 10 | int to, len; 11 | node() {} 12 | node(int t, int l): to(t), len(l) {} 13 | bool operator < (const node& n2) const {return len > n2.len;} //小根堆 14 | }; 15 | 16 | vector* adjList; 17 | 18 | void dijkstra() 19 | { 20 | memset(vis, 0, sizeof(vis)); 21 | memset(dis, 0x3f, sizeof(dis)); 22 | priority_queue q; 23 | q.push(node(start, 0)); dis[start] = 0; 24 | node tmp; 25 | int u, v, tmplen; 26 | while(q.size()) 27 | { 28 | tmp = q.top(); q.pop(); 29 | u = tmp.to; 30 | if(vis[u]) continue; 31 | vis[u] = true; 32 | for(int i=0; i tmplen) 37 | { 38 | dis[v] = tmplen; 39 | q.push(node(v, dis[v])); 40 | } 41 | } 42 | } 43 | } 44 | 45 | 46 | // 2020.06.05默写 47 | const int MAXN = 10005; 48 | int strat; 49 | 50 | bool vis[MAXN]; 51 | int dis[MAXN]; 52 | 53 | class node{ 54 | public: 55 | int to, len; 56 | node() {} 57 | node(int tt, int ll): to(tt), len(ll) {} 58 | bool operator <(const node& n2) const {return len>n2.len;} 59 | }; 60 | 61 | vector *adjList; 62 | 63 | void dijkstra() 64 | { 65 | memset(vis, 0, sizeof(vis)); 66 | memset(dis, 0x3f, sizeof(dis)); 67 | priority_queue q; 68 | q.push(node(start, 0)); dis[start] = 0; 69 | node tmp; int u, v, tmplen; 70 | while(q.size()) 71 | { 72 | tmp = q.top(); q.pop(); 73 | u = tmp.to; 74 | if(vis[u]) continue; 75 | vis[u] = true; 76 | for(int i=0; itmplen) 81 | { 82 | dis[v] = tmplen; 83 | q.push(node(v, dis[v])); 84 | } 85 | } 86 | } 87 | } 88 | 89 | //2020.07.03默写 90 | const int MAXN = 10000; 91 | bool vis[MAXN]; 92 | int dis[MAXN]; 93 | int start; 94 | 95 | class node{ 96 | public: 97 | int to, len; 98 | node() {} 99 | node(int tt, int ll): to(tt), len(ll) {} 100 | bool operator < (const node& n2) const {return len>n2.len;} //最小化堆 101 | }; 102 | 103 | vector *adjList; 104 | 105 | void dijkstra() 106 | { 107 | memset(dis, 0x3f, sizeof(dis)); 108 | memset(vis, 0, sizeof(vis)); 109 | priority_queue q; 110 | q.push(node(start, 0)); dis[start]=0; 111 | node tmp; int u, v, tmplen; 112 | while(q.size()) 113 | { 114 | tmp = q.top(); q.pop(); 115 | u = tmp.to; 116 | if(vis[u]) continue; 117 | vis[u] = true; 118 | for(int i=0; idis[u]+tmplen) 123 | { 124 | dis[v] = dis[u]+tmplen; 125 | q.push(node(v, dis[v])); 126 | } 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /模板代码/disjointSet.cpp: -------------------------------------------------------------------------------- 1 | class disjointset{ 2 | public: 3 | int *parent; 4 | disjointset(int n) 5 | { 6 | parent = new int[n]; 7 | for(int i=0; i parent[root2]) parent[root2] += parent[root1], parent[root1] = root2; 18 | else parent[root1] += parent[root2], parent[root2] = root1; 19 | } 20 | }; -------------------------------------------------------------------------------- /模板代码/maxFlow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int MAXN = 10005; 4 | const int MAXM = 1000005*2; 5 | 6 | int head[MAXN], cur[MAXN], dis[MAXN], n, s, t, cnt=1; // start, terminate 7 | bool vis[MAXN]; 8 | 9 | struct edge{ 10 | int to, next, val; 11 | }e[MAXM]; 12 | 13 | void add(int u, int v, int w) 14 | { 15 | e[++cnt].to = v; // edge下标从2开始(为了之后的异或1操作服务 16 | e[cnt].val = w; 17 | e[cnt].next = head[u]; 18 | head[u] = cnt; 19 | } 20 | 21 | bool bfs() 22 | { 23 | for(int i=0; i<=n; i++) vis[i]=0, cur[i]=head[i]; 24 | queue q; 25 | q.push(s); dis[s]=0; vis[s]=1; 26 | int u, v; 27 | while(q.size()) 28 | { 29 | u = q.front(); q.pop(); 30 | for(int i=head[u]; i; i=e[i].next) 31 | { 32 | v = e[i].to; 33 | if(!vis[v] && e[i].val>0) 34 | { 35 | dis[v] = dis[u]+1; 36 | vis[v] = 1; 37 | if(v == t) return true; 38 | q.push(v); 39 | } 40 | } 41 | } 42 | return false; 43 | } 44 | 45 | int dfs(int now, int flow) // now是当前处理节点,而flow是带进当前节点的流量大小 46 | { 47 | if(flow==0 || now==t) return flow; 48 | int used = 0, v; // used表示用掉了多少当前带进来的流量了 49 | for(int i=cur[now]; i; i=e[i].next) // i=cur[now]是进行了当前边优化,即再次访问到该节点时,之前处理过的边不用再处理了 50 | { 51 | cur[now] = i; // 当前边优化 52 | v = e[i].to; 53 | if(dis[v] != dis[now]+1) continue; //这个不要忘啊!!!!!!! 54 | int tmp = dfs(v, min(flow-used, e[i].val));//探索下一个点,送入的流量要么是当前剩余流量全用完(flow-used)要么是下一条边的容量全用完(e[i].val) 55 | if(tmp) 56 | { 57 | e[i] -= tmp; 58 | e[i^1] += tmp; 59 | used += tmp; 60 | if(flow-used == 0) return flow; 61 | } 62 | } 63 | return used; 64 | } 65 | 66 | int dinic() 67 | { 68 | int ans = 0; 69 | while(bfs()) 70 | ans += dfs(s, 0x7fffffff); 71 | return ans; 72 | } 73 | -------------------------------------------------------------------------------- /模板代码/readWrite.cpp: -------------------------------------------------------------------------------- 1 | inline int read() 2 | { 3 | int X = 0; 4 | char ch = 0; while (ch < '0' || ch > '9') ch = getchar(); 5 | while (ch >= '0' && ch <= '9') X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar(); 6 | return X; 7 | } 8 | 9 | inline void write(int x) 10 | { 11 | int y = 10, len = 1; 12 | while (y <= x) { y *= 10; len++; } 13 | while (len--) { y /= 10; putchar(x / y + 48); x %= y; } 14 | } -------------------------------------------------------------------------------- /模板代码/spfa.cpp: -------------------------------------------------------------------------------- 1 | # include 2 | 3 | int m, n, start; 4 | const int MAXN = 205; 5 | bool vis[MAXN]; 6 | bool dis[MAXN]; 7 | 8 | class node{ 9 | public: 10 | int to, len; 11 | node() {} 12 | node(int t, int l): to(t), len(l) {} 13 | }; 14 | 15 | vector* adjList; 16 | 17 | void spfa() 18 | { 19 | memset(vis, 0, sizeof(vis)); 20 | memset(dis, 0x3f, sizeof(dis)); 21 | queue q; 22 | q.push(start); dis[start] = 0; vis[start] = true; 23 | int u, v, tmplen; 24 | while(q.size()) 25 | { 26 | u = q.front(); q.pop(); 27 | vis[u] = false; 28 | for(int i=0; i dis[u] + tmplen) 33 | { 34 | dis[v] = dis[u] + tmplen; 35 | if(!vis[v])q.push(v), vis[v] = true; 36 | } 37 | } 38 | } 39 | } 40 | 41 | 42 | // 2020.06.06默写 43 | const int MAXN = 1005; 44 | int n, start; 45 | bool vis[MAXN]; 46 | int dis[MAXN]; 47 | 48 | class node{ 49 | public: 50 | int to, len; 51 | node() {} 52 | node(int tt, int ll): to(tt), len(ll) {} 53 | }; 54 | 55 | vector* adjList; 56 | 57 | void spfa() 58 | { 59 | memset(vis, 0, sizeof(vis)); 60 | memset(dis, 0x3f, sizeof(dis)); 61 | queue q; 62 | q.push(start); dis[start]=0; vis[start]=true; 63 | int u, v, tmplen; 64 | while(q.size()) 65 | { 66 | u = q.front(); q.pop(); 67 | vis[u] = false; 68 | for(int i=0; i dis[u]+tmplen) 73 | { 74 | dis[v] = dis[u]+tmplen; 75 | if(!vis[v]) q.push(v), vis[v] = true; 76 | } 77 | } 78 | } 79 | } 80 | 81 | 82 | //2020.07.03默写 83 | const int MAXN = 10005; 84 | bool vis[MAXN]; 85 | int dis[MAXN]; 86 | int start; 87 | 88 | class node{ 89 | public: 90 | int to, len; 91 | node() {} 92 | node(int tt, int ll): to(tt), len(ll) {} 93 | }; 94 | 95 | vector *adjList; 96 | 97 | void spfa() 98 | { 99 | memset(vis, 0, sizeof(vis)); 100 | memset(dis, 0x7f, sizeof(dis)); 101 | queue q; 102 | q.push(start); dis[start]=0; vis[start]=true; 103 | int u, v, tmplen; 104 | while(q.size()) 105 | { 106 | u = q.front(); q.pop(); 107 | vis[u] = false; 108 | for(int i=0; i tmplen) 113 | { 114 | dis[v] = tmplen; 115 | if(!vis[v]) q.push(v), vis[v]=true; 116 | } 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /模板代码/tmp.cpp: -------------------------------------------------------------------------------- 1 | const int MAXN = 50000; 2 | int trees[MAXN]; 3 | int n; 4 | 5 | int lowbit(int x) {return x&(-x);} 6 | 7 | void tadd(int x, int k) 8 | { 9 | while(x<=n) 10 | { 11 | trees[x] += k; 12 | x += lowbit(x); 13 | } 14 | } 15 | 16 | int tsearch(int x) 17 | { 18 | int ans = 0; 19 | while(x) 20 | { 21 | ans += trees[x]; 22 | x -= lowbit(x); 23 | } 24 | return ans; 25 | } -------------------------------------------------------------------------------- /模板代码/treeArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int MAXN = 100005; 6 | int trees[MAXN]; 7 | int a[MAXN]; 8 | 9 | int n; //下标要从1开始 10 | 11 | int lowbit(x) {return x&(-x);} 12 | 13 | void tadd(int x, int k) // x的地方加上k 14 | { 15 | while(x<=n) 16 | { 17 | trees[x] += k; 18 | x += lowbit(x); // 找父节点 19 | } 20 | } 21 | 22 | int tsearch(int x) // 搜索x之前的前缀和 23 | { 24 | int ans = 0; 25 | while(x) 26 | { 27 | ans += trees[x]; 28 | x -= lowbit(x); // 找x的前继节点 29 | } 30 | return ans; 31 | } 32 | 33 | //维护区间最值 34 | void tadd(int x, int k) // 仅建树的时候可以用 35 | { 36 | while(x <= n) 37 | { 38 | trees[x] = max(trees[x], k); 39 | x += lowbit(x); 40 | } 41 | } 42 | /* 43 | 说一下为什么只有建树的时候才可以用,而update的时候不能用。因为假如你修改的是位置x的值为k,并且你是维护最大值,那么你层层往上更新和这个 44 | 点有关的trees的值时,假如用的还是max(trees[x], k),那么假如之前tress[x]里存的最大值恰好是这里位置为x的值,而你这次的k又把这个a[x]改 45 | 小了,那么你这次修改其实并不能反映出这个信息,因为你max一下还是之前的值。所以update函数要另外写一个。 46 | */ 47 | 48 | 49 | int tsearch(int x, int y) 50 | { 51 | int ans = -1; 52 | while(y>=x) 53 | { 54 | ans = max(ans, a[y--]); //先这样搞一下,减少一下y,反正也不亏,还能预防y-lowbit(y)爆出去(小于x) 55 | for(; y-lowbit(y)>=x; y-=lowbit(y)) 56 | ans = max(ans, trees[y]); 57 | } 58 | return ans; 59 | } 60 | /* 61 | 关于最值维护的tsearch说明一下,这里最重要的地方就是理解trees[i]的含义:trees[i]里储存的是从a[i-lowbit(i)+1]到a[i] 62 | 的最大值,而我们在求一段区间[x,y]内的最大值时,若发现y-lowbit(y)>=x,我们就可以用max(ans, trees[y])来求得这一段区间的最值 63 | (因为这段区间包含在我们的目标区间内)。而当y-lowbit(y)=x。不断重复直至y不满足y>=x跳出去。 65 | */ 66 | 67 | void update(int x) //之前已经更新了a[x] = k; 68 | { 69 | int lx, i; 70 | while(x <= n) 71 | { 72 | trees[x] = a[x]; 73 | lx = lowbit(x); 74 | for(int i=1; i