Island
题目描述-戳我跳转
给多个只有一个环的连通图,求每个图中最长链之和
简单来说,给定一个基环树森林,求每个基环树最长链
输入格式
先输入一个 n \mathtt{n} n表示点的个数
接下来对于每个点 i \mathtt{i} i给定 j , L i \mathtt{j,L_i} j,Li,表示 i \mathtt{i} i与 j \mathtt{j} j之间连一条长度为 L i \mathtt{L_i} Li的边
数据范围
对于 100 % \mathtt{100\%} 100%的数据, 2 ⩽ N ⩽ 1 0 6 , 1 ⩽ L i ⩽ 1 0 8 \mathtt{2\leqslant N\leqslant 10^6,1\leqslant L_i\leqslant 10^8} 2⩽N⩽106,1⩽Li⩽108
首先对于基环树有两种处理方式
让 t a \mathtt{ta} ta破环成链
把环当作根节点
很明显两个方法都要用到
解法-基环树+树形DP
首先可以用DFS(depth first search) 求出所有基环树
对于每个基环树可以用DFS(depth first search) 求出 t a \mathtt{ta} ta的环
环当根节点以后很明显我们要求的最长链叫直径
I . \mathrm{I.} I.根在某棵子树中
找子树直径就可以求出这颗树的直径,从小推到大,直接树形 D P \mathtt{DP} DP
I I . \mathrm{II.} II.树的直径经过根且在两个子树中
找到环上两点 i , j \mathtt{i,j} i,j,就可以用树形 D P \mathtt{DP} DP求 d i s i \mathtt{dis_i} disi与 d i s j \mathtt{dis_j} disj,从而算出直径 d i s i + d i s j + l e n i , j \mathtt{dis_i+dis_j+len_{i,j}} disi+disj+leni,j
这里时间会爆,所以要用单调队列优化,此时要破环成链,同时维护一个的前缀和来求解 l e n i , j \mathtt{len_{i,j}} leni,j
所以最后是基环树+树形 D P \mathtt{DP} DP+单调队列+前缀和+ D F S \mathtt{DFS} DFS
就这样做完了!