题意
单源最短路,这里的最短路定义为 \(\sum_{i=1}^kw_i - max_{i=1}^kw_i + min_{i=1}^kw_i\)
就是普通的路径长度减去路径上最大的边权再加上最小的边权
思路
分层图跑 Dij ,可以搞成两个操作,一个是使边权变成 0 ,还有一个是把边权变成两倍。
这样可以使得最短路中变成 0 的一定是最长边, 变成两倍的一定是最短边。
/*
* @Author: zhl
* @LastEditTime: 2021-01-22 09:28:09
*/
#include<bits/stdc++.h>
using namespace std;
const int N = 8e5 + 10, M = 36e5 + 10;
int n, m;
typedef long long ll;
struct Edge {
int to, next;
ll w;
}E[M];
int head[N], tot;
void addEdge(int from,int to,ll w){
E[tot] = { to,head[from],w };head[from] = tot++;
}
void AddEdge(int f,int t,ll w){
addEdge(f, t + n, 0);
addEdge(f, t + 2 * n, 2 * w);
//可以直接转移
addEdge(f, t + 3 * n, w);
addEdge(f + n, t + 3 * n, 2 * w);
addEdge(f + 2 * n, t + 3 * n, 0);
for (int j = 0;j < 4;j++)addEdge(f + j * n, t + j * n, w);
}
void Dijkstra(int s = 1);
int main(){
memset(head, -1, sizeof head);
scanf("%d%d", &n, &m);
for(int i = 1;i <= m;i++){
int f, t;ll w;
scanf("%d%d%lld", &f, &t, &w);
AddEdge(f, t, w);AddEdge(t, f, w);
}
Dijkstra();
for(int i = 2;i <= n;i++){
printf("%lld%c", dis[i + 3 * n], " \n"[i == n]);
}
}