数据结构
biuhongWA
XMU电科院研一学生
展开
-
核弹剑仙 (拓扑排序+bitset或最短路)
题目链接:https://ac.nowcoder.com/acm/contest/6874/F题意:题解:参考了大佬的代码后,得出了两种做法,第一种是拓扑排序,建图时将强的点指向弱的点,同时用bitset进行答案的转移,第二种是将弱的点指向强的点建图,然后对每个点跑一遍最短路,统计那些能到的点的个数(除了它本身)即为答案。拓扑排序代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;con原创 2020-08-22 23:46:33 · 185 阅读 · 0 评论 -
Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree(DFS+贪心)
题目链接:https://codeforces.ml/contest/1401/problem/D题意:n个点,n-1条边,一个数k拆分成若干个素因数将其放置在边上,f(i,j)表示从i顶点到j顶点的边权和,求的最大值。题解:很明显的贪心题,边经过的次数越多,放置的数字越大,因此要先求出每条边经过的次数再从大到小排序,最后分n和m的关系讨论,重点在于如何求每条边的次数,开一个数组sz表示子树大小(节点数),经过边的次数=(n-sz[i])*sz[i],这边简单证明一下,我们从树种任意选取一条边,原创 2020-08-22 03:36:03 · 145 阅读 · 0 评论 -
spfa算法求解次短路
题目链接:https://ac.nowcoder.com/acm/contest/7031/F题意:求图当中从0号节点到n-1号节点的次短路。思路:在spfa算法上稍改进即可,更新次短路的情况分三种。1、当最短路更新时将次短路的值更新为当前最短路的值(这样保证次短路永远都是大于最短路且是第二小的)。2、次短路正常更新。3、当最短路不更新时,若到u的最短路经过该边到v的距离小于次短路则更新次短路。代码:#include<bits/stdc++.h>using namespace原创 2020-08-17 22:08:32 · 415 阅读 · 0 评论 -
Codeforces Round #661 (Div. 3) D. Binary String To Subsequences(队列)
题目链接:https://codeforces.ml/contest/1399/problem/D题意:给一串由0和1组成的字符串,问最少可以分成多少个子序列使得每个子序列没有相邻的0和1.题解:直接模拟标号,同时需要两个队列,q0存的是以0结尾的标号,q1存的是以1结尾的标号,若当前s[i]='0'判断q1是否为空,非空则该元素的标号=队首的标号,再将队首弹出放入q0队列(此标号从以1结尾变成了以0结尾),反之亦然。代码:#include<bits/stdc++.h>usi原创 2020-08-06 15:46:27 · 130 阅读 · 0 评论 -
Codeforces Round #660 (Div. 2) C、D
C. Uncle Bogdan and Country Happiness(两次dfs)题目链接:https://codeforces.ml/contest/1388/problem/C题意:给定一个n个节点的树,所有人都从1号节点往自己回家的方向走,在走的过程中每个人的好心情可能会变成坏心情,但坏心情不能变成好心情,pi是每个节点居住的人数,hi当前节点是好心情的人数-坏心情的人数,问hi计数是否存在。题解:首先要把所有节点经过的总人数算出来(第一次dfs),从而算出每个节点好心情的人数,再将原创 2020-07-31 14:37:22 · 154 阅读 · 0 评论 -
2020牛客寒假算法基础集训营6 图(tarjan缩点+拓扑排序)
题目链接:https://ac.nowcoder.com/acm/contest/3007#question题意:题解:题中有两个坑点,第一个是图可以不连通,第二个是图中有环,因此要先处理环,处理环的过程可以用tarjan算法进行缩点重构图,将所有的环缩成一个点(缩点的细节具体见代码),重构的图是一个有向无环图,因此只要跑一遍拓扑排序,维护每个点的最大值即可。代码:#include<bits/stdc++.h>using namespace std;typedef lo原创 2020-07-27 23:51:24 · 147 阅读 · 0 评论 -
P1726 上白泽慧音 (tarjan求最大强联通分量)
题目链接:https://www.luogu.com.cn/problem/P1726tarjan算法参考:https://blog.csdn.net/Prediction__/article/details/100030166代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=5050;vector<int> e[maxn];int n,m,a,b原创 2020-07-26 00:22:35 · 133 阅读 · 0 评论 -
畅通工程续 (floyd算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874tip:记录一下floyd算法,本质是区间DP的思想,用邻接矩阵存储图,若两个点无边则标记为正无穷,接着枚举中转点k,起点i和终点j,若e[i][j]>e[i][k]+e[k][j]说明从i点到j点经过k点距离更小则更新。代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;const in原创 2020-07-25 17:07:38 · 112 阅读 · 0 评论 -
Codeforces Round #656 (Div. 3) E. Directing Edges (拓扑排序)
题目链接:https://codeforces.ml/contest/1385/problem/E题解:首先将有向边和无向边分开存,若已存在的有向边(判断一个有向图是否存在环用拓扑排序)已经存在环则输出NO,否则一定有解,无向边方向的判断可以根据拓扑排序的先后次序,次序在前的指向次序在后的。代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=2e5+10;int原创 2020-07-23 21:52:02 · 86 阅读 · 0 评论 -
线段树 (区间更新+区间查询)
题目链接:https://www.luogu.com.cn/problem/P3372题意:题解:如果采用单点更新的思路对区间进行更新的话时间复杂度会比较高,因此用了一个lazy数组(俗称懒人标记),它为什么叫懒人标记呢,比如更新的区间为[l,r]+z,而l到r覆盖了线段树某一个节点的区间,那么可以将该节点对应的lazy数组的值加上z,同时更新该节点的值,这样就可以避免更新它子孙节点的值了,当要查询或者修改的时候要将lazy标记往下传一层,这样就能保证当在更新或查询的时候子孙节点的值是正确的。原创 2020-07-07 23:53:09 · 438 阅读 · 0 评论 -
线段树 (单点修改+区间查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166tip:记录一下线段树的入门题吧~~代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=5e5+10;int a[maxn],tree[maxn];int n,m;void build(int node,int start,int end){ if(star原创 2020-07-07 15:57:22 · 256 阅读 · 0 评论 -
最小生成树模板(kruskal算法)
题目链接:https://www.luogu.com.cn/problem/P3366tip:作为队伍的数据结构选手,来记录一下模板题供以后比赛前复习~~~(其实是队友太懒了)题解:这边用了kruskal算法,首先将边权从小到大排序后,再遍历每一条边,用并查集检查当前遍历到的边的两端节点是否已经连通,若不连通则加入到集合中,最后判断一下边是否是节点的数量-1即可。代码:#include<bits/stdc++.h>using namespace std;typedef lo原创 2020-07-03 14:32:11 · 215 阅读 · 0 评论 -
逆序数 (归并排序)
题目链接:https://ac.nowcoder.com/acm/problem/15163题解:求逆序数有两种方法,一个是用归并排序,还有一个是树状数组,当然也可以用冒泡排序但是时间复杂度会变成O(N^2),这边讲一下归并排序的思路。举一个简单的例子吧,L-mid:4 5 ,mid+1-R: 1 2,可以发现4>1那么4后面的数肯定也会大于1(归并排序在marge的时候一定是左右两边都是有序的),因此当前对逆序对数量做出的贡献是mid-i+1,以此类推。代码:#include<b原创 2020-06-26 14:48:06 · 237 阅读 · 0 评论 -
AtCoder Beginner Contest 170 E - Smart Infants(multiset容器模拟)
题目链接:https://atcoder.jp/contests/abc170/tasks/abc170_e题意:给n个人 每个人有一个值a[i] 属于b[i]组 ,有q次询问,每次询问让第c个人变成d组,问每次改变后 , 每个组中的最大值中的最小值为多少。思路:对每个组可以建立一个multiset(它的值可以重复),然后再维护一个multiset保存每个组的最大值。每次进行更新时要注意判断两个条件,第一个是当a[i]值是该组最大时要将该组的最大值插入x,第二个是当a[i]值是要插入那组的最大值时.原创 2020-06-18 14:41:09 · 244 阅读 · 0 评论 -
Maze(dfs+连通块)
题目:思路:由于它只能从+走到-或从-走到+号,可以把迷宫看成由多个连通块或者集合组成的,不需要对每个点都进行dfs,我们只要对于所有连通块的一个点进行dfs即可,因此可以维护一个并查集,但本人太懒。。就直接用了标记,属于某一个连通块的所有点都标记成一样的数字,然后再开一个数组保存该数字对应的个数即可(代码如下)。代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;char a[3005][原创 2020-06-14 22:38:58 · 195 阅读 · 0 评论 -
大数阶乘问题
题目:tip:由于n很大要用到大数模拟才能过,怎么模拟呢,开一个数组每个空间存一定的位数,但是如果只存一位的话会超时,经过多次的WA当每个空间存到7位数时就过了。。要注意的是除了数组末尾前面的数不满7位都要填充0,否则就会丢失掉0,因为是满8位数时进位,每个空间应该是7位数才对。代码:#include<bits/stdc++.h>using namespace std;typedef long long ll;ll a[15000];int main(){ i原创 2020-06-13 02:05:36 · 235 阅读 · 0 评论 -
树上求和(贪心+树上dfs)
题目链接:https://ac.nowcoder.com/acm/contest/5986/F题目:有一棵包含n个节点和n-1条边的树,规定树链(u,v)为树上从u到v的简单路径。树的每条边上都有一个正整数,这个正整数被称作这条边的颜色,规定一条树链的权值w(u,v)为这条树链上所有边的颜色的代数和。而整棵树的权值为所有不同的树链的权值的代数和。已知所有边的颜色集合恰好为1到n-1这n-1个不同的正整数,请你为每条边安排一种颜色,使得这棵树的权值尽量小,你不需要给出具体方案,只需要求出这个最小的权值即原创 2020-06-10 00:08:43 · 274 阅读 · 0 评论 -
Codeforces Round #642 (Div. 3) D. Constructing the Array (优先队列)
https://codeforces.com/contest/1353/problem/D题意:给定一个长度为n的全0数组aa,每次进行以下操作直到所有元素均不为零:在第ii次操作中,取最长的全为0的一段子序列(优先取最左边的),令a[len2/2]=i。其中len为偶数,取l+rl+r或l+r−1。思路:首先题目中要求每次分区间时优先考虑长度最大且最左边的区间优先,因此比较容易想到用优先队列,这里我们将pair键值对放入优先队列中,第一个关键字存长度,第二个关键字存左端点,通过这两个关键词可以将右原创 2020-05-18 09:45:38 · 144 阅读 · 0 评论