摘要:
这次集训,我的收获如下。 自己想出了动态开点线段树、 口胡出了空间复杂度$O(n)$的动态开点权值线段树代替主席树。 学习了后缀数组,字典树。 学习了插头dp与数位dp 学习了A* 学习了基环树dp与仙人掌 学习了决策单调性优化dp 学会了打表当然是法老教的 看到了我和人家的差距(人家三场阿克,我加 阅读全文
摘要:
题面传送门 间隔染色然后跑二分图即可。 不得不说$xht37$的数据一点没改可还行 复杂度$O(n\sqrt m)$ 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) 阅读全文
摘要:
题面传送门 这个对于每个边跑拓扑序即可,如果有环那么不可行,如果两个字母拓扑序相同也不可行。 代码实现: #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; int n 阅读全文
摘要:
题面传送门 直接建分层图跑$spfa$即可。 注意一些细节即可。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define abs(x) ((x)>(0)?(x):-(x)) #define max(a,b) ((a)>(b)? 阅读全文
摘要:
题面传送门 直接跑二分图最大匹配即可。 关于输出方案看哪条边没有权值就输出两个端点即可。 代码实现: #include<cstring> #include<cstdio> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespa 阅读全文
摘要:
题面传送门 显然对列数奇偶性染色然后建边跑二分图即可。 注意无法放置点可能重复。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespace s 阅读全文
摘要:
题面传送门 显然是二分图建模板子题。 观察可得,可以黑白染色建图。 那么从黑格向白格建边跑二分图最小点覆盖即可,注意要用全部点减去最小点覆盖。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a) 阅读全文
摘要:
题面传送门 数据这么小,一看就可以$floyd$ $floyd$外层循环就是允许点转移,那么题目中依次给出允许点转移顺序,那么直接可以做了。 代码实现: #include<cstdio> #include<cstring> #include<algorithm> #define max(a,b) ( 阅读全文
摘要:
题面传送门 一道二分图建模的好题。 题目中要求最少覆盖,很容易想到最小点覆盖,也想到了二分图。 把横竖模板铺出来,可以贪心,一定是延展到最长最优。 那么把图建出来后跑最小点覆盖即可,可以得出最小点覆盖等于最大匹配数。 代码实现: #include<cstdio> #include<cstring> 阅读全文
摘要:
题面传送门 对于左部点建超级原,右部点建超级汇,边权为$1$跑$dicnic$即可,这样超级原控制了每个点只能走一次。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b) 阅读全文
摘要:
题面传送门 直接上$dicnic$板子即可,注意加几个剪枝,跑得飞快。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; i 阅读全文
摘要:
题面传送门 先两遍$dfs$跑出树的直径。 因为所有树的直径都是相类似的,所以只要跑一条直径就好了。 然后在这条直径上尺取。 最后对于直径上每个点的子树不经过直径上的边求距离取最大值即可,这一步很难想,因为如果不取最大值那么就会漏掉答案因为无论如何都是要有这条边的权值的。 完美$O(n)$ 代码实现 阅读全文
摘要:
题面传送门 对于一个点,考虑如果把它和它的子树断开来。 断主要边肯定是断和父节点连着的边。 断次要边统计子树内有几条次要边连向外面。 如果只有一条,那么就断这一天,\(ans++\) 如果没有,那么随便断,加上次要边边数即可。 统计子树内边数可以用树上差分 时间复杂度$O(nlogn)$ 代码实现: 阅读全文
摘要:
题面传送门 题目要求$k$个连接关键点的边权之和的二倍。 那么$ans=dist(a_1,a_2)+dist(a_2,a_3)+...+dist(a_,a_k)$ 那么加入或删除一个点时对左右两边拆边建边即可。 维护左右两边可以用平衡树维护,这里写了一个非递归式权值线段树维护。 时间复杂度$O(nl 阅读全文
摘要:
题面传送门 感觉就像一道裸题。 转化成前缀和然后建边即可。 注意前缀和特性:\(q_i>q_{i-1}\&\&q_-q_{i-1}\leq1\) 所以按照这个建边就好了。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define 阅读全文
摘要:
题面传送门 空间这么小,只能莫队。在移动时用域值分块$O(1)$修改即可。 代码实现: #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n,m,k,x,y,z,ans[1000039],a[1 阅读全文
摘要:
题面传送门 如果$k=1$显然非常简单,取树的直径即可。 考虑$k=2$怎么做。 第一条显然要取树的直径。 而第二条如果围成的环和第一条围成的环有重叠,那么重叠的边要走两次。所以我们可以把这几条重叠的边权值设为$-1$,然后再跑一遍树的直径。 代码实现: #include<cstdio> #incl 阅读全文
摘要:
题面传送门 显然是个结论题。 可以发现,对于每个点,两棵子树肯定差值不大于$1$,而且如果差值为一,那么最晚更新点在左子树,反之在右子树。 然后预处理幂递归即可。 代码实现: #include<cstdio> #define mod 1000000007 using namespace std; i 阅读全文
摘要:
题面传送门 首先把最小生成树跑出来。 然后因为要次小,那么枚举未被选的每一条边。加入树中,构成了一个环,然后在这个环上找严格次小值即可。 关于严格次小值可以用树上倍增求出。 时间复杂度$O(nlognα(n)+nslognlogs)$,其中$s$在这道题中约取$\frac{16}{3}$ 还有一个小 阅读全文
摘要:
题面传送门 可以发现大小具有单调性,所以可以二分。 二分后用$01$背包验证可行性即可。 代码实现: #include<cstdio> #include<cstring> #include<algorithm> #define max(a,b) ((a)>(b)?(a):(b)) using nam 阅读全文
摘要:
题面传送门 显然最长的一条是树的直径。 那么找到树的直径后另一条枚举点然后跑$spfa$即可。 代码实现: #include<cstdio> #include<queue> #include<cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define ma 阅读全文
摘要:
题面传送门 显然可以莫队,而且是板子题。 但是考虑怎么在过程中增加和修改,无论怎样写树形结构都会使复杂度飙升到$n\sqrt nlogn$ 这时可以暴力数据结构:分块,单点修改$O(1)$,查询$O(\sqrt n)$ 这样复杂度就是妥妥的$O(n\sqrt n)$ 代码实现: #include<c 阅读全文
摘要:
题面传送门 这道题是树的直径裸题。 显然跑两遍$dfs$找树的直径即可。 但是输入很毒瘤。 所以要信仰$stringstream$啊 代码实现: #include<bits/stdc++.h> using namespace std; int n,m,k,x,y,z,ans,tot,pus,flag 阅读全文
摘要:
题面传送门 题目中要求最小路径生成树的方案数。 先跑一遍$spfa$把最小路径跑出来,然后对于每个点枚举边,看看有几个点是可以转移,然后乘法原理计数即可。 代码实现: #include<cstdio> #include<cstring> #include<queue> #include<algori 阅读全文
摘要:
题面传送门 题目大意:构造一个完全图,使得在最小生成树唯一(题目中给出)的情况下权值总和最小。 直接克鲁斯卡尔模拟,在合并两棵树时进行操作。 合并两棵树时要连的边的条数是$siz_x\times siz_y-1$,即将合并的这条边一定是两棵树中最大的边,而所有不在最小生成树内的边一定大于这条边,所以 阅读全文