Lecture

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 16

树与图杂题选讲

2022-10-02
Ptz Camp 2017 Jagiellonian U Contest
Problem J. Spoonerisms
• 给定 n 个字符串,问是否存在一对 (A,B) ,使得 A 能拆成 pq,B 能
拆成 rs ,且 C=ps 和 D=rq 也在这 n 个串中出现

• n<=500000,Σ|S|<=500000
Ptz Camp 2017 Jagiellonian U Contest
Problem J. Spoonerisms
• 需要想到建图
• 用 trie 树把前缀和后缀提取出来然后同一个串的前缀和后缀之间
连边,则原题转化为找一个四元环的问题。
• 四元环问题可以在 O(n*sqrt(n)) 的时间内解决
Ptz Camp 2017 Jagiellonian U Contest
Problem J. Spoonerisms
• 这里讲一下无向图三元环 / 四元环计数问题:

• 三元环计数:把点按度数从大到小排序,同度数按编号排序
• 排序后,无向边视作有向边,序号小的向序号大的连边

• 枚举一个点 u ,先标记它的直接到达点 w ,然后找它的二步到达


点 u->v->w ,若该点被标记则计数
Ptz Camp 2017 Jagiellonian U Contest
Problem J. Spoonerisms
• 考虑复杂度分析:
• 问题只可能出现在 v->w 的遍历次数上
• 遍历次数是 in[v]
• 而 in[v]<=sqrt(m)
• 每个连向 v 的 u ,入度都 >=in[v]
• 也就是有 in[v] 条边的入度 >=in[v]
• in[v]^2<=m
Ptz Camp 2017 Jagiellonian U Contest
Problem J. Spoonerisms
• 四元环计数的方式为:
• 按上面方式排序,然后 u->v->w, num[w]+=1
• 最后答案为 C(num[w],2)
• 时间复杂度分析同三元环
HDU 6331 walking plan
• 给定一个 n 个点 ,m 条边的有向带权图,走一条边我们称为走一

• q 次询问,每次询问走 >=k 步的的情况下,从 s 到 t 的最短路

• n<=50,m<=n*(n-1),q<=10^5,k<=10^4
HDU 6331 walking plan
• 考虑暴力是用 Floyd 算出走 k 步从 s 到 t 的最短路,预处理 O(kn^3) ,无法接受
• 我们考虑平衡预处理和查询两部分的复杂度:
• 考虑 k=100*q+r
• 我们预处理 g[q][s][t] 表示恰好走 q*100 步,从 s 到 t 的最短路
• 然后零散部分 r ,我们预处理 f[r][s][t] 表示走 r 步,从 s 到 t 的最短路
• dis[r][s][t] 表示走 >=r 步,从 s 到 t 的最短路
• >=r 怎么处理呢?
• 我们考虑走 n 步一定会出现一个环,那么 dis[r][s][t]=min(f[r][s][t],f[r+1][s][t],
……,f[r+n][s][t])
• 回答时候把 k 拆成两部分,然后枚举中转点 z ,答案是 min(g[q][s][z]+dis[r][z][t])
• 复杂度 O(sqrt(k)*n^3+qn)
2016 BZOJ 十连测 Claris contest day2
• 有 n 个点,编号为 1~n ,开始有 m 条单向边。每个点有一个编码
val ,如果 val[i] and val[j] = val[j] ,那么 i->j 也有一条单向边。边
权都为 1 ,求 1 号点到每一个点的距离。

• n<=2*10^5 , m<=3*10^5 , 1<=val<2^20


2016 BZOJ 十连测 Claris contest day2
• 最暴力的做法是两两判断是否有边然后建边, O(n^2)
• 我们考虑从建图上来优化:我们对每个权值建一个虚点,然后每
个点朝对应的虚点连边,边权为 1 ,虚点朝该 val 的点连边,边
权为 0
• 然后虚点之间怎么办?
• 我们发现 val[i] and val[j] = val[j] 表示二进制集合表示下 ,j 是 i 的子

• 于是我们用枚举子集的技巧,虚点 x 向它的子集连边权为 0 的边,
可以把边数缩到 O(3^20)
2016 BZOJ 十连测 Claris contest day2
• 我们考虑哪些边是冗余的
• 我们实际上每次只需要在原来集合上少掉一个 1 ,这样一层一层下来就可
以找到所有子集点
• 这样每个虚点最多连出 20 条边,边数 O(20*2^20)
• 这个边数跑 Dijkstra 是不行的
• 我们考虑这个图的特殊性质:边权只有 0 和 1 ,是一个 01 最短路
• 于是我们用 bfs 来做这个东西
• 如果是边权为 0 的边,塞到队头,边权为 1 的边,塞到队尾
• 这样最短路过程就是线性的了
• 总复杂度 O(20*2^20)
The 18th Zhejiang Provincial Collegiate Programming Contest D.
Shortest Path Query

• 给定一个 n 个点 m 条边的带权无向图,保证每条边 (u_i,v_i,w_i)


满足 u_i 的二进制表示是 v_i 的前缀 ( 如 :2 的二进制表示是 10 ,
5 的二进制表示是 101 ,则 2 可以向 5 连边 )
• 现在有 q 次询问,每次询问两个点 s 和 t 之间的最短路

• n,m,q<=200000
The 18th Zhejiang Provincial Collegiate Programming Contest D.
Shortest Path Query

• 我们先建立 Trie 树
• 对于一对询问 (s,t) ,我们取它们二进制的公共前缀
• 这对应 Trie 树上从 LCA(s,t) 到根的一条路径
• 如 101010 和 101011 ,取公共前缀之后为 10101
• 那么这条 LCA(s,t) 到根的路径为 1,10,101,1010,10101
• 可以发现, (s,t) 的最短路一定会经过这几个点其中之一,且完全
在它的子树里
The 18th Zhejiang Provincial Collegiate Programming Contest D.
Shortest Path Query

• 那么我们把询问离线下来挂在 LCA(s,t) 到根路径的每个点上 , 每次


对一个点的子树跑 dijkstra, 然后用这个点作为中转点更新答案
• 这里的子树限制可以通过计算 Trie 树的 dfs 序获得
• 考虑每层都是总共 O(n) 个点的 dijkstra ,而 Trie 共有 log 层
• 因此时间复杂度为 O(nlog^2n)
XXI Open Cup named after E.V. Pankratiev.
Grand Prix of Korea
• 一个区间图的每个顶点代表一个区间,两个顶点代表的区间有交
则这两个顶点有边相连
• 现在给定一些带权区间,你要删掉一些区间,使得区间图没有环,
删除的区间权值和最小
XXI Open Cup named after E.V. Pankratiev.
Grand Prix of Korea
• 条件可以转化成每个点至多被两个区间覆盖,然后可以建出一个
最小费用流的图
• 因为存在负边,所以不能直接用 dijkstra 费用流
• 注意到图是一个 DAG ,因此可以用 DP 求出第一次最短路之后使
用 Dijkstra
• 复杂度 O(nlogn)

You might also like