最短路图trick
最短路图
这是一个图论的小trick。
对于一些只能在最短路上操作且可能同时存在多条最短路的问题,可以试着采用建最短路图的方法:将最短路径上的边放在一个新的图中,使得问题能够在一个DAG(有向无环图)上操作。
大致的方法是:
若我们需要 \(1-n\) 的最短路图,我们可以先从 \(1\) 开始跑一遍最短路,得到 \(dis1[i]\) ,然后在反图上跑一遍 \(n\) 最短路 \(dis2[i]\) 。然后枚举每条边,若边 \((u,v,w)\) 满足 \(dis1[u]+w+dis2[v]=dis1[n]\) ,那么这条边在最短路图上。
具体实现看例题:
例题:取边方案
题目描述
给你一张有 \(n\) 个点 \(m\) 条边的无向连通图,每条边有边权,设 \(disa_i\) 表示这张图中点 \(i\) 到点 \(1\) 的距离。
现在要求你在这张图中删去 \(m-(n-1)\) 条边,使得这张图变成一棵树,设 \(dib_i\) 为这棵树中点 \(i\) 到 点 \(1\) 的最短距离。
现在求解有多少种删边方案,使得对于任意的 \(i\) ,都有 \(disa_i=disb_i\) 。
输入格式
第一行包含两个正整数 \(n,m\) ,表示无向连通图的点数和边数。
接下来有 \(m\) 行,每行有 \(3\) 个正整数 \(u,v,w\) ,表示点 \(u\) 和点 \(v\) 之间有一条边权为 \(w\) 的无向边。
数据保证无重边、无自环。
输出格式
输出一行一个整数,表示满足条件的方案数对 \(2147483647\) 取模的结果。
样例输入
3 3
1 2 2
1 3 1
2 3 1
样例输出
2
样例解释
删去 \(1st\) or \(3rd\) 边都能满足条件。
由定义我们可以知道,在本题中只要是最短路图的生成树,都是合法的。
所以只需要枚举生成树个数就可以了。
如何高效枚举?
枚举生成树,可以看做给每个点选一个父亲,那么每个点可选的父亲数就是这个点的入度,那么入度之积就是答案了。