https://loj.ac/problem/2587#submit_code (题面来自LOJ) 考试时候发觉树很可做,并且写了一个dp骗到了树的分. 苦于不会圆方树……现在回来发现这题还是很可做的! 先套路套圆方树,然后思考路径条数如何计算. 一个显然的想法:从一个点双-> 一个点双->……-> 一个点双,条数没准就是每个点双的大小! 于是我们能够想到方点的权值为点双的大小. 当然注意到我们选择的起点/终点以及每个点双之间相邻的切点只能走一次,为了去重,我们把圆点权值设为-1. 则任…
 [APIO2018] 铁人两项 题目大意: 给定一张图,问有多少三元组(a,b,c)(a,b,c 互不相等)满足存在一条点不重复的以a为起点,经过b,终点为c的路径 如果你不会圆方树 ----------------------- 放弃是最好的选择(先学了再来吧) 如果你会圆方树 考虑\((a,...,c)\) 1.如果a,c不同属一个点双,不难发现答案为路上经过的(点双的节点个数)的和减去割点数 2.如果a,c同属一个点双,那么答案为本点双的节点个数 - 2 自然地想到方点的权值为内含节点个…
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方树,枚举中间点$b$,一对合法的$a,c$需要使这两个点位于与$b$直接相连的方点的不同子树中.树形$DP$,对圆点和方点分别统计答案即可. #include<set> #include<map> #include<queue> #include<stack>…
把这个图缩成圆方树,把方点的权值设成-1,圆点的权值设成点双的size,算 经过这个点的路径的数量*这个点的点权 的和即是答案. #include <iostream> #include <cstdio> #include <cstring> using namespace std; ; struct Edge{ int to[N],nxt[N],head[N],ecnt; Edge(){ecnt=;} void add(int bg,int ed) {nxt[++ec…
过了14个月再重新看这题,发现圆方树从来就没有写过.然后写了这题发现自己APIO2018打铁的原因竟然是没开long long,将树的部分的O(n)写挂了(爆int),毕竟去年APIO时我啥都不会,连tarjan都写不来,活该打铁. 不扯了写题解. 首先建立圆方树,然后任意枚举圆点s和f,然后c可以在这两个点路径中每个点双的点挑选.所以令圆点值为-1,方点值为点双大小,然后选法是圆点路径权值和.然后计算每个点出现多少次,可以对每个连通块树形DP求解,然后这道题就没了. #include<bits…
传送门 题意简述:给你一张无向图,问你满足存在从a−>b−>ca->b->ca−>b−>c且不经过重复节点的路径的有序点对(a,b,c)(a,b,c)(a,b,c)的数量. 思路: 对每一个连通块建一棵圆方树,然后可以按照圆点和方点做不同的树形dpdpdp. 圆点:找存在于两棵不同子树的点对数 方点:找存在于三颗不同子树的点对数. 代码: #include<bits/stdc++.h> #define ri register int using namesp…
题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两方点之间的圆点会计算两次,所以圆点权值设为-1就好了. 那么现在有 \(n^2\) 个点对,求每个点对之间的路径上点的权值和. 对每个点计算一下被计算次数就可以了.这个路径次数计算注意考虑全.. 另外点对是圆点间的,所以方点初始sz[]为0,圆点的sz[]才是1. 方点其实建一条边就可以. LOJ为什么找…
分析 根据题目中的要求,从\(s\)出发前往\(f\)一定可以,并且只可能经过这两个结点所在的点双连通分量和它们之间的点双连通分量,因此切换点\(c\)只能从这些点中选取. 建出圆方树后,因为圆方树上一条路径的两个端点(圆点)不能作为切换点,并且路径上其他的圆点都被两个路径上的点双连通分量所包含,可以发现,如果把方点的权值设为这个点双连通分量的\(siz\),圆点的权值设为\(-1\),那么圆方树上所有两个端点都是圆点的路径的权值和就是答案.这个问题可以通过考虑每个结点在多少条路径上来解决. 时…
传送门 又学会了一个新东西好开心呢~ 思路 显然,假如枚举了起始点\(x\)和终止点\(y\),中转点就必须在它们之间的简单路径上. 不知为何想到了圆方树,可以发现,如果把方点的权值记为双联通分量的大小,圆点权值记为-1,那么\(x \rightarrow y\)的答案就是树上\(x\rightarrow y\)的路径权值和. 直接枚举\(O(n^2)\),点分治\(O(n\log n)\),考虑每个点被经过的次数乘上它的权值即可\(O(n)\). 注意图可能不连通. 代码 #include<b…
题目链接 LOJ. BZOJ. Solution 先建圆方树. 我们考虑暴力,枚举一个点对,我们枚举的点都是圆点,然后统计中间那个点可以取的位置的数量,加起来就是答案. 那么怎么统计呢,我们对于每个点赋一个点权,方点点权为点双的大小,圆点点权为\(-1\). 那么这条路径的点权和就是答案,注意要统计到端点的权值. 然后优化就很显然了,直接枚举每个点被算了多少次就行了,这个随便算一下就好了. 复杂度\(O(n)\). #include<bits/stdc++.h> using namespace…