线图

  • 如图,每个L(L(T))上的点对应T上的一条三点链
  • 在连接L(L(T))上两点,当且仅当两点代表的三点链在T上有共边,且边权为 共边边权*2+非共边1边权+非共边2边权
  • 在L(L(T))上从点u走到点v,等价于u代表的三点链在T上删掉自己的一条边,然后在剩下来的两个点上选一个点接一条边,转化为v代表的三点链,代价为 不动边边权*2+删边边权+接边边权
  • 先考虑两个三点链在树上的最短路。此处不赘述,大体上的分类讨论如图:
  • 拓展到求任意两三点链的最短路径总和,可以用树形DP实现,考虑如何做到不重不漏:
    1.首先每对不相交三点链的贡献可以拆成两部分:树上最短路径的贡献+三点链的贡献。三点链的贡献只与树上最短路径连接的是三点链的中点还是端点有关,与具体选择什么样的最短路径无关:

    一条边作为树上最短路径的一部分时,贡献永远是自身边权*4
    所以我们可以对每条边分别讨论它 作为三点链的一部分的贡献 和 作为树上最短路的一部分的贡献,再把这两部分的贡献加起来。
    2.再考虑相交的三点链对。
    对于X型,我们对每条边讨论它为四边中第1小、第2小、第3小、第4小边时自身的贡献,再把这些贡献加起来。
    对于Y型,边(u,v)(u=fa[v],u的度数为d)作为Y型的共边出现的情况有(d−1)(d−2)/2(d-1)(d-2)/2(d−1)(d−2)/2种,作为非共边出现的情况有(d−1)(d−2)(d-1)(d-2)(d−1)(d−2)种,我们在扫到这条边时直接给答案加上(d−1)(d−2)/2×4×边权(d-1)(d-2)/2\times4\times边权(d−1)(d−2)/2×4×边权即可。
    对于Z型,我们在共边处统计出整个Z型的贡献。

ps:为保证不重不漏地考虑到所有的三点链,我们在DP到树节点u时,就只考虑以u为中点的三点链

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int N=5e5+5;
const int mod=998244353;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
int add(int a,int b){return (a+b)%mod;}
int dec(int a,int b){return ((a-b)%mod+mod)%mod;}
void Add(int &a,int b){a=add(a,b);}
struct Edge{int v,w,nxt;
}e[N<<1];
int n,d[N],head[N],cnt=0,ans;
int f[N],g[N];
//f[i]:i子树内三点链的个数
//g[i]:i子树外三点链的个数
int addedge(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
}
void dfs(int u,int ff){f[u]=1ll*d[u]*(d[u]-1)/2%mod;for(int i=head[u];i;i=e[i].nxt){if(e[i].v!=ff){dfs(e[i].v,u);Add(f[u],f[e[i].v]);}}
}
int to[N],val[N],Sw[N];
int su[N],sv[N];
int pre[N],suf[N];
bool cmp(int a,int b){return val[a]<val[b];
}
void work(int u,int ff){for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(v==ff) continue;work(v,u);}int tot=0;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;to[++tot]=v;val[v]=e[i].w; Add(Sw[u],e[i].w);su[v]=v==ff?f[u]:g[v];sv[v]=v==ff?g[u]:f[v];}sort(to+1,to+tot+1,cmp);pre[0]=suf[tot+1]=0; for(int i=1;i<=tot;i++) pre[i]=add(pre[i-1],sv[to[i]]);for(int i=tot;i;i--) suf[i]=add(suf[i+1],sv[to[i]]);for(int i=1;i<=tot;i++){int v=to[i],du=d[u],dv=d[v],w=val[v];//处理这条边为相交的三点链做的贡献 Add(ans,1ll*(tot-i)*(tot-i-1)*(tot-i-2)/6*9%mod*w%mod);//以u为中心的X型,当前边为第1小边 Add(ans,1ll*(i-1)*(tot-i)*(tot-i-1)/2*7%mod*w%mod);//以u为中心的X型,当前边为第2小边 Add(ans,1ll*(i-1)*(i-2)/2*(tot-i)*5%mod*w%mod);//以u为中心的X型,当前边为第3小边 Add(ans,1ll*(i-1)*(i-2)*(i-3)/6*3%mod*w%mod);//以u为中心的X型,当前边为第4小边 Add(ans,1ll*(tot-1)*(tot-2)/2*4%mod*w%mod);//以u为中心的Y型if(v!=ff) Add(ans,1ll*(du-1)*(dv-1)*2%mod*w%mod+add(1ll*(Sw[u]-w)*(dv-1)%mod,1ll*(Sw[v]-w)*(du-1)%mod));//以u为中心的Z型 //处理这条边为不相交的三点链做的贡献 if(v!=ff) Add(ans,1ll*(sv[v]-(dv-1))*(su[v]-(du-1))*4%mod*w%mod);//这条边在树上最短路径中,注意if Add(ans,1ll*dec(su[v],1ll*du*(du-1)/2%mod)*(tot-2)%mod*w%mod); Add(ans,1ll*dec(su[v],pre[i-1]+1ll*du*(du-1)/2%mod)*(tot-i-1)%mod*2*w%mod);Add(ans,1ll*dec(su[v],suf[i+1]+1ll*du*(du-1)/2%mod)*(tot-i)%mod*2*w%mod);//树上最短路径连中点uAdd(ans,(1ll*(tot-1)*3*w%mod+1ll*(Sw[u]-w))*(sv[v]-(dv-1))%mod);//树上最短路径连端点v }
}
signed main(){n=read();for(int i=1;i<n;i++){int u=read(),v=read(),w=read();addedge(u,v,w);addedge(v,u,w);d[u]++;d[v]++;}dfs(1,0);for(int i=1;i<=n;i++) g[i]=f[1]-f[i];work(1,0);cout<<dec(ans,0)<<endl;return 0;
}

[XSY] 线图(树形DP、分类讨论)相关推荐

  1. 2020牛客多校9:B. Groundhog and Apple Tree(树形DP + 分类讨论 + 贪心)

    题目大意:有一棵苹果树,每个节点有一个苹果,吃掉 uuu 点的苹果能获得 aua_uau​点 HP,经过第 iii 条边需要消耗 wiw_iwi​ HP,在原地等待一秒可以获得 111 HP,每条边只 ...

  2. Py之matplotlibseaborn :高级图可视化之​​​​​​​Q-Q分位数图probplot、​​​​​​​boxplot箱线图、stripplot分类散点图案例应用及代码实现

    Py之matplotlib&seaborn :高级图可视化之Q-Q分位数图probplot.boxplot箱线图.stripplot分类散点图案例应用及代码实现 目录 基于百分位数原理寻找异常 ...

  3. P2331 [SCOI2005]最大子矩阵(DP分类讨论)

    P2331 [SCOI2005]最大子矩阵(DP&分类讨论) 考虑dp解决. 若m=1m=1m=1则是一个简单的递推. 若m=2m=2m=2则是分情况讨论. 一个是当前行不取. 一个是选第一列 ...

  4. P3842 [TJOI2007]线段(线性dp,分类讨论)

    P3842 [TJOI2007]线段 题意 [TJOI2007]线段 题目描述 在一个 n×nn \times nn×n 的平面上,在每一行中有一条线段,第 iii 行的线段的左端点是(i,Li)(i ...

  5. [BZOJ3677/UOJ#105][APIO2014]Beads and wires 连珠线(树形dp+换根)

    Address https://www.lydsy.com/JudgeOnline/problem.php?id=3677 http://uoj.ac/problem/105 Solution 考虑一 ...

  6. 【线性 dp】A005_LC_不同的子序列(记忆化 / dp 分类讨论)

    一.Problem 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 题目数据保证答案符合 32 位带符号整数范围. 示例 1: 输入:S = "rabbbit ...

  7. ggplot2-绘图-箱线图

    目录 一.前面的啰嗦 二.绘图数据说明 三.基本箱线图 四.分组箱线图 1. 单分类变量的分组箱线图 1.1 基本版 1.2 美化版 2. 双分类变量的分组箱线图 2.1 基本版 2.2 美化版 五. ...

  8. [XSY] 树与图(树形DP、生成函数、分治NTT、重链剖分)

    树与图 如果真的在图上跑算法,那么光建图复杂度就O(n2logn)O(n^2logn)O(n2logn)了,这显然不可行.所以一定要把 在图上的操作 转换成 在树上的操作 在图上删去点u,相当于在树上 ...

  9. 【PKUSC2019】线弦图【计数】【树形DP】【分治FFT】

    Description 定义线图为把无向图的边变成点,新图中点与点之间右边当且仅当它们对应的边在原图中有公共点,这样得到的图. 定义弦图为不存在一个长度大于3的纯环,纯环的定义是在环上任取两个不相邻的 ...

最新文章

  1. 学python需要买书吗-最适合Python初学者的6本书籍推荐「必须收藏」
  2. WINCE6.0更换桌面壁纸和图标
  3. [Python图像识别] 四十九.图像生成之什么是生成对抗网络GAN?基础原理和代码普及
  4. [科技]Loj#6564-最长公共子序列【bitset】
  5. 直线的端点画垂线的lisp_【以课说法】线段、射线、直线
  6. linux 进程间读写锁,Linux系统编程—进程间同步
  7. Fiddler——模拟限速
  8. Windows搭建kms服务器
  9. SQL Server 数据库增删改查语句
  10. 港股配资系统搭建(适合量化交易)
  11. 【嵌入式系统开发12】在stm32F103C8T6环境下,用HAL库,采用中断模式编程,控制LED的高亮与熄灭
  12. Java 岗面经:两年半经验,面 10 个公司,经 28 轮面试,拿 9 个 offer,涨麻了。
  13. linux内核如何支持多核cpu,现在的多核CPU,Linux操作系统是否能够实现单个进程(多线程)的多核调度(跨CPU核心调度)?...
  14. clipboard剪切板
  15. Lambda和Stream流
  16. Java Web项目源代码|CRM客户关系管理系统项目实战(Struts2+Spring+Hibernate)解析+源代码+教程
  17. 汽车变速系统的换挡律
  18. 计算机系统中必不可少的系统软件是哪个,计算机系统中必不可少的软件
  19. 小学写景作文无处下手?心田花开8大写作技巧
  20. IELTS学习(001) - 语法构成原理

热门文章

  1. php imagick加GD实现gif图换脸动画生成表情包制作功能
  2. linux下查看进程+杀死进程方法大全
  3. 丢失LDF文件怎么办?
  4. 【安卓】【高德地图】调用 mMapView?.onDestroy() 崩溃
  5. 基于Matlab的图像分割----边缘检测
  6. yum命令,yum本地源,共享yum源
  7. 美图手机sim卡显示无服务器,美图手机卡顿怎么解决
  8. 第三章:Solr4.7以DIH的方式从数据库导数据
  9. win10磁盘占用100%
  10. OpenGL学习之材质RGB值和光源RGB值关系