Loading

CF 1473E Minimum Path

题意

单源最短路,这里的最短路定义为 \(\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]);
	}
}
posted @ 2021-01-22 15:58  —O0oO-  阅读(121)  评论(0编辑  收藏  举报