(最短路)17bupt新生赛——F. ch追妹
F. ch追妹 2017新生赛
时间限制 2000 ms 内存限制 65536 KB
题目描述
n个点的一张无向图,每条边长度为wi,ch站在a点,ch要追的妹子站在b点。ch可以使用一次膜法,将一条边的长度变为0。ch想知道他要追到妹子要走的最短路径。
输入格式
第一行为数据组数T(T≤10)。
每组数据的第一行为四个数 n,m,a,b(1≤a,b≤n≤10000,1≤m≤50000),分别表示点数,边数,ch的位置,妹子的位置。
之后m行,每行为三个数 u,v,w(1≤u,v≤n;1≤w≤10000),表示u,v之间有一条长度为w的无向边。数据保证没有重边和自环(即不会出现u到u的边,也不会出现两条u到v的边)。
输出格式
对每组数据输出一行,表示ch要走的最近距离。数据确保a可以到达b。
输入样例
2
2 1 1 2
1 2 2
4 4 1 4
1 2 2
2 4 2
1 3 1
3 4 10
输出样例
0
1
与普通的最短路差别在于可以将一条边长度改为0,为此用d[x] x∈[1,n]表示没有进行将某条边长度改为0的操作时到某点x的最短路长度,d[x+n]表示进行过一次将某条边长度改为0的操作时到某点x
的最短长度。
下面分析一下何时更新值。
采用dijkstra算法,每次到一个点u时,d[u]是最短的,此时u的取值有两种可能,一种是<=n,另一种是>n
如果是<=n,那么此时还没有进行将某边改为0的操作,将从u点连出去的所有边进行2种判断,设某边连到v点,边长为x。
若d[v]>d[u]+x,将d[v]更新为d[u]+x,并push入队列
若d[v+n]>d[u],将d[v+n]更新为d[u],push入队列
如果>n
若d[v+n]>d[u]
d[v+n]=d[u]push入队列。
整个队列用优先队列的方式维护。