最近看了看最短路树,于是就来做这道题了qwq(我才不会告诉你是因为看了这道题才去看的最短路树)

<mstyle mathcolor="red"> , d i j k t r a 西 , , ( ) </mstyle> \color{red}所谓最短路树,就是在跑dijktra的时候随手记录个小东西,然后形成一个树,这棵树的根节点(也就是最短路起点)到每个节点的距离就是源点到该点的最短路 ,dijktra西,,()

<mstyle mathcolor="orange"> : n 1 , </mstyle> \color{orange}然后最短路树有一个神奇的性质:就是只要不破坏树上的n-1条边,源点到各点的最短路就不会变 :n1,


<mstyle mathcolor="green"> , , , </mstyle> \color{green}然后,这道题的做法就是选择要删除的边,然后再跑最短路,并与之前的比较 ,,,

<mstyle mathcolor="brown"> , , , </mstyle> \color{brown}然后,我们有最短路树之后,我们就不用枚举每条边了,只需要尝试删除最短路树上的边就行了 ,,,

<mstyle mathcolor="grey"> ( q w q ) </mstyle> \color{grey}(反正删掉别的地方的边也不会影响最短路qwq) (qwq)


<mstyle mathcolor="blue"> , q w q </mstyle> \color{blue}现在,唯一的问题就是怎么来建立最短路树了qwq ,qwq

<mstyle mathcolor="purple"> , , p r e [ i ] i , d a t a [ i ] i </mstyle> \color{purple}首先,我们要额外维护几个数组,pre[i]代表i号节点最短路前面连的边,data[i]代表i号节点最短路前面的点 ,,pre[i]i,data[i]i

<mstyle mathcolor="white"> . . . . </mstyle> \color{white}然后....就没有然后了 ....

<mstyle mathcolor="yellow"> </mstyle> \color{yellow}现在就是上代码了

<mstyle mathcolor="orange"> . . . . . </mstyle> \color{orange}然后唯一的技巧就是..... .....

            if(dis[v] > dis[u] + a[i].z ) { // 转移最短路的时候,顺手记录一下qwq
            	data[v] = u ;
            	pre[v] = i ; 
                dis[v] = dis[u] + a[i].z ;
                q.push(make_pair(dis[v],v)) ;
            }

<mstyle mathcolor="red"> q w q </mstyle> \color{red}下面真的放代码了qwq qwq

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define maxn 2100000 
#pragma GCC optimize(5)
using namespace std ;
int data[maxn] , pre[maxn] ;
struct dy{
	int x , y , z , next ;
}a[maxn] ;
int head[maxn] , vis[maxn] , dis[maxn] , t ;
int read() {
	int x = 0 , f = 1 ; char s = getchar() ;
	while(s > '9' || s < '0') {if(s == '-') f = -1 ; s = getchar() ;}
	while(s <='9' && s >='0') {x = x * 10 + (s-'0'); s = getchar() ;}
	return x*f ;
}
void add(int x ,int y ,int z) {
	a[++t].x = x ;
	a[t].y = y ;
	a[t].z = z ;
	a[t].next = head[x] ;
	head[x] = t ;
}
typedef pair<int,int>pa ;
void dijkstra(int s) {
    memset(dis,0x3f,sizeof(dis)) ;
    memset(vis,0,sizeof(vis)) ;
    priority_queue<pa,vector<pa>,greater<pa> >q ;
    dis[s] = 0 , vis[s] = 0 ;
    q.push(make_pair(dis[s],s)) ;
    while(!q.empty()) {
        int u = q.top().second ;
        q.pop() ;
        if(vis[u]) continue ;
        vis[u] = 1 ;
        for(int i = head[u] ; i ; i = a[i].next ) {
            int v = a[i].y ;
            if(dis[v] > dis[u] + a[i].z ) {
            	data[v] = u ;
            	pre[v] = i ; 
                dis[v] = dis[u] + a[i].z ;
                q.push(make_pair(dis[v],v)) ;
            }
        }
    }
} 
int n , m ;
int Vis[maxn] ;
int main () {
	n = read() , m = read() ;
	for(int i = 1 ; i <= m ; i ++) {
		int x = read () , y = read() , z = read() ;
		add(x,y,z) ;
		add(y,x,z) ;
	}
	dijkstra(1) ;
	int num = 0 ;
	for(int i = n ; i ; i = data[i]) { 
		 Vis[++num] = pre[i] ;
 	}
	int ans = dis[n] ;
	for(int i = 1 ; i <= num ; i ++ ) {
		int v = Vis[i] ;
		int res = a[v].z ;
		a[v].z = 999999999 ;
		dijkstra(1) ;
		a[v].z = res ;
		ans = max(ans,dis[n]) ;
	}
	cout << ans <<endl ;
	return 0 ;
} 

<mstyle mathcolor="purple"> ! </mstyle> \color{purple}完结散花! !